MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-pvfs2.c
blob6c135274dc3faac6531cfa92a915395e460b65e7
1 /* packet-pvfs.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 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-smb.c and others
14 * TODO
16 * - Add filename snooping (match file handles with file names),
17 * similar to how packet-rpc.c/packet-nfs.c implements it
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "config.h"
36 #include <string.h>
37 #include <ctype.h>
39 #include <glib.h>
41 #include <epan/packet.h>
42 #include <epan/exceptions.h>
43 #include <epan/prefs.h>
44 #include <epan/wmem/wmem.h>
45 #include <epan/strutil.h>
46 #include "packet-tcp.h"
48 #define TCP_PORT_PVFS2 3334
50 #define PVFS2_FH_LENGTH 8
52 /* Header incl. magic number, mode, tag, size */
53 #define BMI_HEADER_SIZE 24
55 /* desegmentation of PVFS over TCP */
56 static gboolean pvfs_desegment = TRUE;
58 /* Forward declaration we need below */
59 void proto_reg_handoff_pvfs(void);
61 /* Initialize the protocol and registered fields */
62 static int proto_pvfs = -1;
63 static int hf_pvfs_magic_nr = -1;
64 static int hf_pvfs_uid = -1;
65 static int hf_pvfs_gid = -1;
66 static int hf_pvfs_mode = -1;
67 static int hf_pvfs_tag = -1;
68 static int hf_pvfs_size = -1;
69 /* static int hf_pvfs_release_number = -1; */
70 static int hf_pvfs_encoding = -1;
71 static int hf_pvfs_server_op = -1;
72 /* static int hf_pvfs_handle = -1; */
73 static int hf_pvfs_fs_id = -1;
74 static int hf_pvfs_attrmask = -1;
75 static int hf_pvfs_attr = -1;
76 static int hf_pvfs_ds_type = -1;
77 static int hf_pvfs_error = -1;
78 static int hf_pvfs_atime = -1;
79 static int hf_pvfs_atime_sec = -1;
80 static int hf_pvfs_atime_nsec = -1;
81 static int hf_pvfs_mtime = -1;
82 static int hf_pvfs_mtime_sec = -1;
83 static int hf_pvfs_mtime_nsec = -1;
84 static int hf_pvfs_ctime = -1;
85 static int hf_pvfs_ctime_sec = -1;
86 static int hf_pvfs_ctime_nsec = -1;
87 static int hf_pvfs_parent_atime = -1;
88 static int hf_pvfs_parent_atime_sec = -1;
89 static int hf_pvfs_parent_atime_nsec = -1;
90 static int hf_pvfs_parent_mtime = -1;
91 static int hf_pvfs_parent_mtime_sec = -1;
92 static int hf_pvfs_parent_mtime_nsec = -1;
93 static int hf_pvfs_parent_ctime = -1;
94 static int hf_pvfs_parent_ctime_sec = -1;
95 static int hf_pvfs_parent_ctime_nsec = -1;
96 static int hf_pvfs_distribution = -1;
97 static int hf_pvfs_dfile_count = -1;
98 static int hf_pvfs_dirent_count = -1;
99 static int hf_pvfs_directory_version = -1;
100 static int hf_pvfs_path = -1;
101 static int hf_pvfs_total_completed = -1;
102 static int hf_pvfs_io_dist = -1;
103 static int hf_pvfs_aggregate_size = -1;
104 static int hf_pvfs_io_type = -1;
105 static int hf_pvfs_flowproto_type = -1;
106 static int hf_pvfs_server_param = -1;
107 static int hf_pvfs_prev_value = -1;
108 /* static int hf_pvfs_ram_free_bytes = -1; */
109 static int hf_pvfs_bytes_available = -1;
110 static int hf_pvfs_bytes_total = -1;
111 static int hf_pvfs_ram_bytes_total = -1;
112 static int hf_pvfs_ram_bytes_free = -1;
113 static int hf_pvfs_load_average_1s = -1;
114 static int hf_pvfs_load_average_5s = -1;
115 static int hf_pvfs_load_average_15s = -1;
116 static int hf_pvfs_uptime_seconds = -1;
117 static int hf_pvfs_handles_available = -1;
118 static int hf_pvfs_handles_total = -1;
119 static int hf_pvfs_unused = -1;
120 static int hf_pvfs_context_id = -1;
121 static int hf_pvfs_offset = -1;
122 static int hf_pvfs_stride = -1;
123 static int hf_pvfs_lb = -1;
124 static int hf_pvfs_ub = -1;
125 static int hf_pvfs_end_time_ms = -1;
126 static int hf_pvfs_cur_time_ms = -1;
127 static int hf_pvfs_start_time_ms = -1;
128 static int hf_pvfs_bytes_written = -1;
129 static int hf_pvfs_bytes_read = -1;
130 static int hf_pvfs_metadata_write = -1;
131 static int hf_pvfs_metadata_read = -1;
132 static int hf_pvfs_b_size = -1;
133 static int hf_pvfs_k_size = -1;
134 static int hf_pvfs_id_gen_t = -1;
135 static int hf_pvfs_attribute_key = -1;
136 static int hf_pvfs_attribute_value = -1;
137 static int hf_pvfs_strip_size = -1;
138 static int hf_pvfs_ereg = -1;
139 static int hf_pvfs_sreg = -1;
140 static int hf_pvfs_num_eregs = -1;
141 static int hf_pvfs_num_blocks = -1;
142 static int hf_pvfs_num_contig_chunks = -1;
143 static int hf_pvfs_server_nr = -1;
144 static int hf_pvfs_server_count = -1;
145 static int hf_pvfs_fh_length = -1;
146 static int hf_pvfs_fh_hash = -1;
147 static int hf_pvfs_permissions = -1;
148 static int hf_pvfs_server_mode = -1;
149 static int hf_pvfs_depth = -1;
150 static int hf_pvfs_num_nested_req = -1;
151 static int hf_pvfs_committed = -1;
152 static int hf_pvfs_refcount = -1;
153 static int hf_pvfs_numreq = -1;
154 static int hf_pvfs_truncate_request_flags = -1;
155 static int hf_pvfs_ds_position = -1;
156 static int hf_pvfs_dirent_limit = -1;
157 static int hf_pvfs_flush_request_flags = -1;
158 static int hf_pvfs_next_id = -1;
159 static int hf_pvfs_mgmt_perf_mon_request_count = -1;
160 static int hf_pvfs_mgmt_perf_mon_request_event_count = -1;
161 static int hf_pvfs_lookup_path_response_handle_count = -1;
162 static int hf_pvfs_getconfig_response_total_bytes = -1;
163 static int hf_pvfs_getconfig_response_lines = -1;
164 static int hf_pvfs_getconfig_response_config_bytes = -1;
165 static int hf_pvfs_mgmt_perf_mon_response_suggested_next_id = -1;
166 static int hf_pvfs_mgmt_perf_stat_valid_flag = -1;
167 static int hf_pvfs_mgmt_perf_stat_id = -1;
168 static int hf_pvfs_mgmt_perf_mon_response_perf_array_count = -1;
169 static int hf_pvfs_mgmt_iterate_handles_response_ds_position = -1;
170 static int hf_pvfs_mgmt_iterate_handles_response_handle_count = -1;
171 static int hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count = -1;
172 static int hf_pvfs_mgmt_event_mon_response_api = -1;
173 static int hf_pvfs_mgmt_event_mon_response_operation = -1;
174 static int hf_pvfs_mgmt_event_mon_response_value = -1;
175 static int hf_pvfs_mgmt_event_mon_response_flags = -1;
176 static int hf_pvfs_mgmt_event_mon_response_tv_sec = -1;
177 static int hf_pvfs_mgmt_event_mon_response_tv_usec = -1;
179 /* Initialize the subtree pointers */
180 static gint ett_pvfs = -1;
181 static gint ett_pvfs_hdr = -1;
182 static gint ett_pvfs_credentials = -1;
183 static gint ett_pvfs_server_config = -1;
184 static gint ett_pvfs_server_config_branch = -1;
185 static gint ett_pvfs_attrmask = -1;
186 static gint ett_pvfs_time = -1;
187 static gint ett_pvfs_extent_array_tree = -1;
188 static gint ett_pvfs_extent_item = -1;
189 static gint ett_pvfs_string = -1;
190 static gint ett_pvfs_attr_tree = -1;
191 static gint ett_pvfs_distribution = -1;
192 static gint ett_pvfs_mgmt_perf_stat = -1;
193 static gint ett_pvfs_mgmt_dspace_info = -1;
194 static gint ett_pvfs_attr = -1;
195 static gint ett_pvfs_fh = -1;
197 #define BMI_MAGIC_NR 51903
199 static const value_string names_pvfs_mode[] =
201 #define TCP_MODE_IMMED 1
202 { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
203 #define TCP_MODE_UNEXP 2
204 { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
205 #define TCP_MODE_EAGER 4
206 { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
207 #define TCP_MODE_REND 8
208 { TCP_MODE_REND, "TCP_MODE_REND" },
209 { 0, NULL }
212 static const value_string names_pvfs_encoding[] =
214 #define PVFS_ENCODING_DIRECT 1
215 { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
216 #define PVFS_ENCODING_LE_BFIELD 2
217 { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
218 #define PVFS_ENCODING_XDR 3
219 { PVFS_ENCODING_XDR, "ENCODING_XDR" },
220 { 0, NULL }
223 static const value_string names_pvfs_io_type[] =
225 #define PVFS_IO_READ 1
226 { PVFS_IO_READ, "PVFS_IO_READ" },
227 #define PVFS_IO_WRITE 2
228 { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
229 { 0, NULL }
232 static const value_string names_pvfs_flowproto_type[] =
234 #define FLOWPROTO_DUMP_OFFSETS 1
235 { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
236 #define FLOWPROTO_BMI_CACHE 2
237 { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
238 #define FLOWPROTO_MULTIQUEUE 3
239 { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
240 { 0, NULL }
243 static const value_string names_pvfs_server_param[] =
245 #define PVFS_SERV_PARAM_INVALID 0
246 { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
247 #define PVFS_SERV_PARAM_GOSSIP_MASK 1
248 { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
249 #define PVFS_SERV_PARAM_FSID_CHECK 2
250 { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
251 #define PVFS_SERV_PARAM_ROOT_CHECK 3
252 { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
253 #define PVFS_SERV_PARAM_MODE 4
254 { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
255 #define PVFS_SERV_PARAM_EVENT_ON 5
256 { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
257 #define PVFS_SERV_PARAM_EVENT_MASKS 6
258 { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
259 { 0, NULL }
262 static const value_string names_pvfs_server_mode[] =
264 #define PVFS_SERVER_NORMAL_MODE 1
265 { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
266 #define PVFS_SERVER_ADMIN_MODE 2
267 { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
268 { 0, NULL }
271 /* Forward declaration */
272 static gboolean
273 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
274 gboolean dissect_other_as_continuation);
277 static int dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
279 dissect_pvfs_common(tvb, pinfo, tree, FALSE);
280 return tvb_reported_length(tvb);
283 static guint get_pvfs_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
285 guint32 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_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
298 guint32 magic_nr, mode;
299 guint64 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 const value_string names_pvfs_server_op[] =
342 #define PVFS_SERV_INVALID 0
343 { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
344 #define PVFS_SERV_CREATE 1
345 { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
346 #define PVFS_SERV_REMOVE 2
347 { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
348 #define PVFS_SERV_IO 3
349 { PVFS_SERV_IO, "PVFS_SERV_IO" },
350 #define PVFS_SERV_GETATTR 4
351 { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
352 #define PVFS_SERV_SETATTR 5
353 { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
354 #define PVFS_SERV_LOOKUP_PATH 6
355 { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
356 #define PVFS_SERV_CRDIRENT 7
357 { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
358 #define PVFS_SERV_RMDIRENT 8
359 { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
360 #define PVFS_SERV_CHDIRENT 9
361 { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
362 #define PVFS_SERV_TRUNCATE 10
363 { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
364 #define PVFS_SERV_MKDIR 11
365 { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
366 #define PVFS_SERV_READDIR 12
367 { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
368 #define PVFS_SERV_GETCONFIG 13
369 { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
370 #define PVFS_SERV_WRITE_COMPLETION 14
371 { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
372 #define PVFS_SERV_FLUSH 15
373 { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
374 #define PVFS_SERV_MGMT_SETPARAM 16
375 { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
376 #define PVFS_SERV_MGMT_NOOP 17
377 { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
378 #define PVFS_SERV_STATFS 18
379 { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
380 #define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
381 { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
382 #define PVFS_SERV_MGMT_PERF_MON 20
383 { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
384 #define PVFS_SERV_MGMT_ITERATE_HANDLES 21
385 { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
386 #define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
387 { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
388 #define PVFS_SERV_MGMT_EVENT_MON 23
389 { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
390 #define PVFS_SERV_MGMT_REMOVE_OBJECT 24
391 { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
392 #define PVFS_SERV_MGMT_REMOVE_DIRENT 25
393 { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
394 #define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
395 { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
396 #define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
397 { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
398 #define PVFS_SERV_PROTO_ERROR 28
399 { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
400 #define PVFS_SERV_GETEATTR 29
401 { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
402 #define PVFS_SERV_SETEATTR 30
403 { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
404 #define PVFS_SERV_DELEATTR 31
405 { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
406 { 0, NULL }
409 /* special bits used to differentiate PVFS error codes from system
410 * * errno values
411 * */
412 #define PVFS_ERROR_BIT (1 << 30)
414 /* a shorthand to make the error code definitions more readable */
415 #define E(num) (num|PVFS_ERROR_BIT)
417 static const value_string names_pvfs_error[] = {
418 { 0, "Success" },
419 #define PVFS_EPERM E(1) /* Operation not permitted */
420 { PVFS_EPERM, "PVFS_EPERM" },
421 #define PVFS_ENOENT E(2) /* No such file or directory */
422 { PVFS_ENOENT, "PVFS_ENOENT" },
423 #define PVFS_EINTR E(3) /* Interrupted system call */
424 { PVFS_EINTR, "PVFS_EINTR" },
425 #define PVFS_EIO E(4) /* I/O error */
426 { PVFS_EIO, "PVFS_EIO" },
427 #define PVFS_ENXIO E(5) /* No such device or address */
428 { PVFS_ENXIO, "PVFS_ENXIO" },
429 #define PVFS_EBADF E(6) /* Bad file number */
430 { PVFS_EBADF, "PVFS_EBADF" },
431 #define PVFS_EAGAIN E(7) /* Try again */
432 { PVFS_EAGAIN, "PVFS_EAGAIN" },
433 #define PVFS_ENOMEM E(8) /* Out of memory */
434 { PVFS_ENOMEM, "PVFS_ENOMEM" },
435 #define PVFS_EFAULT E(9) /* Bad address */
436 { PVFS_EFAULT, "PVFS_EFAULT" },
437 #define PVFS_EBUSY E(10) /* Device or resource busy */
438 { PVFS_EBUSY, "PVFS_EBUSY" },
439 #define PVFS_EEXIST E(11) /* File exists */
440 { PVFS_EEXIST, "PVFS_EEXIST" },
441 #define PVFS_ENODEV E(12) /* No such device */
442 { PVFS_ENODEV, "PVFS_ENODEV" },
443 #define PVFS_ENOTDIR E(13) /* Not a directory */
444 { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
445 #define PVFS_EISDIR E(14) /* Is a directory */
446 { PVFS_EISDIR, "PVFS_EISDIR" },
447 #define PVFS_EINVAL E(15) /* Invalid argument */
448 { PVFS_EINVAL, "PVFS_EINVAL" },
449 #define PVFS_EMFILE E(16) /* Too many open files */
450 { PVFS_EMFILE, "PVFS_EMFILE" },
451 #define PVFS_EFBIG E(17) /* File too large */
452 { PVFS_EFBIG, "PVFS_EFBIG" },
453 #define PVFS_ENOSPC E(18) /* No space left on device */
454 { PVFS_ENOSPC, "PVFS_ENOSPC" },
455 #define PVFS_EROFS E(19) /* Read-only file system */
456 { PVFS_EROFS, "PVFS_EROFS" },
457 #define PVFS_EMLINK E(20) /* Too many links */
458 { PVFS_EMLINK, "PVFS_EMLINK" },
459 #define PVFS_EPIPE E(21) /* Broken pipe */
460 { PVFS_EPIPE, "PVFS_EPIPE" },
461 #define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
462 { PVFS_EDEADLK, "PVFS_EDEADLK" },
463 #define PVFS_ENAMETOOLONG E(23) /* File name too long */
464 { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
465 #define PVFS_ENOLCK E(24) /* No record locks available */
466 { PVFS_ENOLCK, "PVFS_ENOLCK" },
467 #define PVFS_ENOSYS E(25) /* Function not implemented */
468 { PVFS_ENOSYS, "PVFS_ENOSYS" },
469 #define PVFS_ENOTEMPTY E(26) /* Directory not empty */
470 { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
471 #define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
472 { PVFS_ELOOP, "PVFS_ELOOP" },
473 #define PVFS_EWOULDBLOCK E(28) /* Operation would block */
474 { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
475 #define PVFS_ENOMSG E(29) /* No message of desired type */
476 { PVFS_ENOMSG, "PVFS_ENOMSG" },
477 #define PVFS_EUNATCH E(30) /* Protocol driver not attached */
478 { PVFS_EUNATCH, "PVFS_EUNATCH" },
479 #define PVFS_EBADR E(31) /* Invalid request descriptor */
480 { PVFS_EBADR, "PVFS_EBADR" },
481 #define PVFS_EDEADLOCK E(32)
482 { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
483 #define PVFS_ENODATA E(33) /* No data available */
484 { PVFS_ENODATA, "PVFS_ENODATA" },
485 #define PVFS_ETIME E(34) /* Timer expired */
486 { PVFS_ETIME, "PVFS_ETIME" },
487 #define PVFS_ENONET E(35) /* Machine is not on the network */
488 { PVFS_ENONET, "PVFS_ENONET" },
489 #define PVFS_EREMOTE E(36) /* Object is remote */
490 { PVFS_EREMOTE, "PVFS_EREMOTE" },
491 #define PVFS_ECOMM E(37) /* Communication error on send */
492 { PVFS_ECOMM, "PVFS_ECOMM" },
493 #define PVFS_EPROTO E(38) /* Protocol error */
494 { PVFS_EPROTO, "PVFS_EPROTO" },
495 #define PVFS_EBADMSG E(39) /* Not a data message */
496 { PVFS_EBADMSG, "PVFS_EBADMSG" },
497 #define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
498 { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
499 #define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
500 { PVFS_ERESTART, "PVFS_ERESTART" },
501 #define PVFS_EMSGSIZE E(42) /* Message too long */
502 { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
503 #define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
504 { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
505 #define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
506 { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
507 #define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
508 { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
509 #define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
510 { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
511 #define PVFS_EADDRINUSE E(47) /* Address already in use */
512 { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
513 #define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
514 { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
515 #define PVFS_ENETDOWN E(49) /* Network is down */
516 { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
517 #define PVFS_ENETUNREACH E(50) /* Network is unreachable */
518 { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
519 #define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
520 { PVFS_ENETRESET, "PVFS_ENETRESET" },
521 #define PVFS_ENOBUFS E(52) /* No buffer space available */
522 { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
523 #define PVFS_ETIMEDOUT E(53) /* Connection timed out */
524 { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
525 #define PVFS_ECONNREFUSED E(54) /* Connection refused */
526 { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
527 #define PVFS_EHOSTDOWN E(55) /* Host is down */
528 { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
529 #define PVFS_EHOSTUNREACH E(56) /* No route to host */
530 { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
531 #define PVFS_EALREADY E(57) /* Operation already in progress */
532 { PVFS_EALREADY, "PVFS_EALREADY" },
533 #define PVFS_EACCES E(58) /* Operation already in progress */
534 { PVFS_EACCES, "PVFS_EACCES" },
535 { 0, NULL }
538 static int
539 dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
540 packet_info *pinfo)
542 gint32 err;
543 const char *errmsg = NULL;
545 err = tvb_get_letohl(tvb, offset);
546 proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
547 offset += 4;
549 if (err != 0)
551 errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
552 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
555 return offset;
558 static int
559 dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
560 int offset)
562 proto_item *item;
563 proto_tree *hcred_tree;
564 guint32 uid, gid;
566 uid = tvb_get_letohl(tvb, offset);
567 gid = tvb_get_letohl(tvb, offset + 4);
569 item = proto_tree_add_text(parent_tree, tvb, offset, 8,
570 "Credentials (UID: %d, GID: %d)", uid, gid);
571 hcred_tree = proto_item_add_subtree(item, ett_pvfs_credentials);
573 /* UID */
574 proto_tree_add_item(hcred_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
575 offset += 4;
577 /* GID */
578 proto_tree_add_item(hcred_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
579 offset += 4;
581 return offset;
584 static const value_string names_pvfs_attr[] =
586 #define PVFS_ATTR_COMMON_UID (1 << 0)
587 #define PVFS_ATTR_BIT_COMMON_UID 0
588 { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
590 #define PVFS_ATTR_COMMON_GID (1 << 1)
591 #define PVFS_ATTR_BIT_COMMON_GID 1
592 { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
594 #define PVFS_ATTR_COMMON_PERM (1 << 2)
595 #define PVFS_ATTR_BIT_COMMON_PERM 2
596 { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
598 #define PVFS_ATTR_COMMON_ATIME (1 << 3)
599 #define PVFS_ATTR_BIT_COMMON_ATIME 3
600 { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
602 #define PVFS_ATTR_COMMON_CTIME (1 << 4)
603 #define PVFS_ATTR_BIT_COMMON_CTIME 4
604 { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
606 #define PVFS_ATTR_COMMON_MTIME (1 << 5)
607 #define PVFS_ATTR_BIT_COMMON_MTIME 5
608 { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
610 #define PVFS_ATTR_COMMON_TYPE (1 << 6)
611 #define PVFS_ATTR_BIT_COMMON_TYPE 6
612 { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
614 #if 0
615 #define PVFS_ATTR_COMMON_ALL \
616 (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
617 PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
618 PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
619 PVFS_ATTR_COMMON_TYPE)
620 #endif
622 /* internal attribute masks for metadata objects */
623 #define PVFS_ATTR_META_DIST (1 << 10)
624 #define PVFS_ATTR_BIT_META_DIST 10
625 { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
627 #define PVFS_ATTR_META_DFILES (1 << 11)
628 #define PVFS_ATTR_BIT_META_DFILES 11
629 { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
631 #if 0
632 #define PVFS_ATTR_META_ALL \
633 (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
634 #endif
636 /* internal attribute masks for datafile objects */
637 #define PVFS_ATTR_DATA_SIZE (1 << 15)
638 #define PVFS_ATTR_BIT_DATA_SIZE 15
639 { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
641 #if 0
642 #define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
643 #endif
645 /* internal attribute masks for symlink objects */
646 #define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
647 #define PVFS_ATTR_BIT_SYMLINK_TARGET 18
648 { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
650 #if 0
651 #define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
652 #endif
654 /* internal attribute masks for directory objects */
655 #define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
656 #define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
657 { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
659 #if 0
660 #define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
661 #endif
663 /* attribute masks used by system interface callers */
664 #define PVFS_ATTR_SYS_SIZE (1 << 20)
665 #define PVFS_ATTR_BIT_SYS_SIZE 20
666 { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
668 #define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
669 #define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
670 { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
672 #define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
673 #define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
674 { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
676 #define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
677 #define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
678 { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
680 #if 0
681 #define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
682 #define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
683 #define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
684 #define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
685 #define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
686 #define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
687 #define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
688 #endif
689 { 0, NULL }
692 #if 0
693 #define PVFS_ATTR_SYS_ALL \
694 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
695 PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
696 PVFS_ATTR_SYS_DIRENT_COUNT)
698 #define PVFS_ATTR_SYS_ALL_NOSIZE \
699 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
700 PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
702 #define PVFS_ATTR_SYS_ALL_SETABLE \
703 (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
704 #endif
707 static int
708 dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
709 guint32 *pattrmask)
711 guint32 attrmask, i;
712 proto_item *attritem;
713 proto_tree *attrtree;
715 attrmask = tvb_get_letohl(tvb, offset);
717 attritem = proto_tree_add_uint(tree, hf_pvfs_attrmask, tvb, offset, 4, attrmask);
718 attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
720 for (i = 0; i < 32; i++)
722 if (attrmask & (1 << i))
723 proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
726 offset += 4;
728 if (pattrmask)
729 *pattrmask = attrmask;
731 return offset;
734 static const value_string names_pvfs_ds_type[] = {
735 #define PVFS_TYPE_NONE 0
736 { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
737 #define PVFS_TYPE_METAFILE (1 << 0)
738 { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
739 #define PVFS_TYPE_DATAFILE (1 << 1)
740 { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
741 #define PVFS_TYPE_DIRECTORY (1 << 2)
742 { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
743 #define PVFS_TYPE_SYMLINK (1 << 3)
744 { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
745 #define PVFS_TYPE_DIRDATA (1 << 4)
746 { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
747 { 0, NULL }
750 static int
751 dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
752 int *pds_type)
754 guint32 ds_type;
756 ds_type = tvb_get_letohl(tvb, offset);
758 proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
760 offset += 4;
762 if (pds_type)
763 *pds_type = ds_type;
765 return offset;
768 #define roundup4(x) (((x) + 3) & ~3)
769 #define roundup8(x) (((x) + 7) & ~7)
771 static int
772 dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
773 proto_tree *tree,
774 packet_info *pinfo _U_,
775 int hfindex,
776 gboolean fixed_length, guint32 length,
777 gboolean string_data, char const **string_buffer_ret)
779 int data_offset;
780 proto_item *string_item = NULL;
781 proto_tree *string_tree = NULL;
783 guint32 string_length;
784 guint32 string_length_full;
785 guint32 string_length_packet;
786 guint32 string_length_captured;
787 guint32 string_length_copy;
789 int fill_truncated;
790 guint32 fill_length;
791 guint32 fill_length_packet;
792 guint32 fill_length_captured;
793 guint32 fill_length_copy;
795 int exception = 0;
797 char *string_buffer = NULL;
798 const char *string_buffer_print = NULL;
800 if (fixed_length) {
801 string_length = length;
802 data_offset = offset;
803 } else {
804 string_length = tvb_get_letohl(tvb,offset+0);
805 data_offset = offset + 4;
808 * Variable-length strings include NULL terminator on-the-wire but
809 * NULL terminator is not included in string length.
812 if (string_data)
813 string_length += 1;
816 string_length_captured = tvb_length_remaining(tvb, data_offset);
817 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
820 * Strangeness... the protocol basically says that the length plus
821 * the string must be padded out to an 8-byte boundary.
824 if (!string_data)
825 string_length_full = roundup4(string_length);
826 else
827 string_length_full = roundup8(4 + string_length);
829 if (string_length_captured < string_length) {
830 /* truncated string */
831 string_length_copy = string_length_captured;
832 fill_truncated = 2;
833 fill_length = 0;
834 fill_length_copy = 0;
836 if (string_length_packet < string_length)
837 exception = ReportedBoundsError;
838 else
839 exception = BoundsError;
841 else {
842 /* full string data */
843 string_length_copy = string_length;
845 if (!string_data)
846 fill_length = string_length_full - string_length;
847 else
848 fill_length = string_length_full - string_length - 4;
850 fill_length_captured = tvb_length_remaining(tvb,
851 data_offset + string_length);
852 fill_length_packet = tvb_reported_length_remaining(tvb,
853 data_offset + string_length);
855 if (fill_length_captured < fill_length) {
856 /* truncated fill bytes */
857 fill_length_copy = fill_length_packet;
858 fill_truncated = 1;
859 if (fill_length_packet < fill_length)
860 exception = ReportedBoundsError;
861 else
862 exception = BoundsError;
864 else {
865 /* full fill bytes */
866 fill_length_copy = fill_length;
867 fill_truncated = 0;
871 if (string_data) {
872 char *tmpstr;
874 tmpstr = (char *) tvb_get_string(wmem_packet_scope(), tvb, data_offset,
875 string_length_copy);
877 string_buffer = (char *)memcpy(wmem_alloc(wmem_packet_scope(), string_length_copy+1), tmpstr, string_length_copy);
878 } else {
879 string_buffer = (char *) tvb_memcpy(tvb,
880 wmem_alloc(wmem_packet_scope(), string_length_copy+1), data_offset, string_length_copy);
883 string_buffer[string_length_copy] = '\0';
885 /* calculate a nice printable string */
886 if (string_length) {
887 if (string_length != string_length_copy) {
888 if (string_data) {
889 char *formatted;
890 guint16 string_buffer_size = 0;
892 formatted = format_text((guint8 *)string_buffer,
893 (int)strlen(string_buffer));
895 string_buffer_size = (guint16)strlen(formatted) + 12 + 1;
897 /* alloc maximum data area */
898 string_buffer_print = (char*) wmem_alloc(wmem_packet_scope(), string_buffer_size);
899 /* copy over the data */
900 g_snprintf((char *)string_buffer_print, string_buffer_size,
901 "%s<TRUNCATED>", formatted);
902 /* append <TRUNCATED> */
903 /* This way, we get the TRUNCATED even
904 in the case of totally wrong packets,
905 where \0 are inside the string.
906 TRUNCATED will appear at the
907 first \0 or at the end (where we
908 put the securing \0).
910 } else {
911 string_buffer_print="<DATA><TRUNCATED>";
913 } else {
914 if (string_data) {
915 string_buffer_print =
916 wmem_strdup(wmem_packet_scope(), format_text((guint8 *) string_buffer,
917 (int)strlen(string_buffer)));
918 } else {
919 string_buffer_print="<DATA>";
922 } else {
923 string_buffer_print="<EMPTY>";
926 if (tree) {
927 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
928 "%s: %s", proto_registrar_get_name(hfindex),
929 string_buffer_print);
931 if (string_item)
932 string_tree = proto_item_add_subtree(string_item,
933 ett_pvfs_string);
935 if (!fixed_length) {
936 if (string_tree)
937 proto_tree_add_text(string_tree, tvb,offset+0,4,
938 "length: %u (excl. NULL terminator)", string_length - 1);
939 offset += 4;
942 if (string_tree) {
943 if (string_data) {
944 proto_tree_add_string_format(string_tree,
945 hfindex, tvb, offset, string_length_copy,
946 string_buffer,
947 "contents: %s", string_buffer_print);
948 } else {
949 proto_tree_add_bytes_format(string_tree,
950 hfindex, tvb, offset, string_length_copy,
951 (guint8 *) string_buffer,
952 "contents: %s", string_buffer_print);
956 offset += string_length_copy;
958 if (fill_length) {
959 if (string_tree) {
960 if (fill_truncated) {
961 proto_tree_add_text(string_tree, tvb,
962 offset,fill_length_copy,
963 "fill bytes: opaque data<TRUNCATED>");
965 else {
966 proto_tree_add_text(string_tree, tvb,
967 offset,fill_length_copy,
968 "fill bytes: opaque data");
971 offset += fill_length_copy;
974 if (string_item)
975 proto_item_set_end(string_item, tvb, offset);
977 if (string_buffer_ret != NULL)
978 *string_buffer_ret = string_buffer_print;
981 * If the data was truncated, throw the appropriate exception,
982 * so that dissection stops and the frame is properly marked.
984 if (exception != 0)
985 THROW(exception);
987 return offset;
990 static int
991 dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
992 int offset, const char **string_buffer_ret)
994 return dissect_pvfs_opaque_data(tvb, offset, tree, NULL, hfindex,
995 FALSE, 0, TRUE, string_buffer_ret);
998 static void
999 dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
1001 guint sublen;
1002 guint bytes_left;
1003 gboolean first_line;
1005 bytes_left = PVFS2_FH_LENGTH;
1006 first_line = TRUE;
1007 while (bytes_left != 0) {
1008 sublen = 16;
1009 if (sublen > bytes_left)
1010 sublen = bytes_left;
1011 proto_tree_add_text(tree, tvb, offset, sublen,
1012 "%s%s",
1013 first_line ? "data: " :
1014 " ",
1015 tvb_bytes_to_str(tvb,offset,sublen));
1016 bytes_left -= sublen;
1017 offset += sublen;
1018 first_line = FALSE;
1022 static void
1023 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1024 proto_tree *tree, guint32 *hash)
1026 guint32 fhhash;
1027 guint32 i;
1029 /* Not all bytes there. Any attempt to deduce the type would be
1030 senseless. */
1031 if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
1032 goto type_ready;
1034 /* create a semiunique hash value for the filehandle */
1035 for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
1036 guint32 val;
1037 val = tvb_get_ntohl(tvb, offset+i);
1038 fhhash ^= val;
1039 fhhash += val;
1042 proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
1043 fhhash);
1045 if (hash)
1046 *hash = fhhash;
1048 /* TODO: add file name snooping code here */
1050 type_ready:
1051 dissect_fhandle_data_unknown(tvb, offset, tree);
1054 static int
1055 dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
1056 proto_tree *tree, const char *name, guint32 *hash)
1058 proto_item* fitem = NULL;
1059 proto_tree* ftree = NULL;
1061 fitem = proto_tree_add_text(tree, tvb, offset, PVFS2_FH_LENGTH,
1062 "%s", name);
1063 ftree = proto_item_add_subtree(fitem, ett_pvfs_fh);
1065 /* TODO: add fh to file name snooping code here */
1067 proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
1068 PVFS2_FH_LENGTH);
1070 dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
1072 offset += PVFS2_FH_LENGTH;
1074 return offset;
1077 static int
1078 dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
1079 packet_info *pinfo, guint32 nCount)
1081 proto_item *extent_item;
1082 proto_tree *extent_tree;
1084 extent_item = proto_tree_add_text(tree, tvb, offset, 8, "Item %d", nCount);
1085 extent_tree = proto_item_add_subtree(extent_item, ett_pvfs_extent_item);
1087 /* first handle */
1088 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
1089 NULL);
1091 /* last handle */
1092 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
1093 NULL);
1095 return offset;
1098 static int
1099 dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
1100 packet_info *pinfo)
1102 guint32 extent_count;
1103 guint32 nCount;
1104 proto_item *extent_array_item;
1105 proto_tree *extent_array_tree;
1107 /* extent count */
1108 extent_count = tvb_get_letohl(tvb, offset);
1110 extent_array_item = proto_tree_add_text(tree, tvb, offset, 4,
1111 "Handle Extent Array (count = %d)", extent_count);
1113 offset += 4;
1115 if (extent_count > 0)
1117 extent_array_tree = proto_item_add_subtree(extent_array_item,
1118 ett_pvfs_extent_array_tree);
1120 /* Add extent array items */
1121 for (nCount = 0; nCount < extent_count; nCount++)
1122 offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
1123 pinfo, nCount);
1126 return offset;
1129 static int
1130 dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
1131 int hf_time, int hf_time_sec, int hf_time_nsec)
1133 guint32 seconds;
1134 guint32 nseconds;
1135 nstime_t ts;
1136 proto_item *time_item;
1137 proto_tree *time_tree;
1139 ts.secs = seconds = tvb_get_letohl(tvb, offset);
1140 ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
1142 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
1143 time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
1145 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
1146 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4, nseconds);
1148 offset += 8;
1149 return offset;
1152 static
1153 int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
1154 int hfindex, guint64 *pvalue)
1156 guint64 val;
1158 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1159 tvb_get_letohl(tvb, offset);
1161 proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
1163 if (pvalue)
1164 *pvalue = val;
1166 return offset + 8;
1169 /* Taken from pvfs2-dist-simple-stripe.h */
1170 #define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
1171 #define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
1173 static int
1174 dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset)
1176 proto_item *dist_item = NULL;
1177 proto_tree *dist_tree = NULL;
1178 guint32 distlen = 0;
1179 char *tmpstr = NULL;
1180 guint8 issimplestripe = 0;
1182 /* Get distribution name length */
1183 distlen = tvb_get_letohl(tvb, offset);
1185 /* Get distribution name */
1186 tmpstr = (char *) tvb_get_string(wmem_packet_scope(), tvb, offset + 4, distlen);
1188 if (tree)
1190 guint32 total_len;
1192 /* 'distlen' does not include the NULL terminator */
1193 total_len = roundup8(4 + distlen + 1);
1195 if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
1196 (g_ascii_strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
1197 distlen) == 0))
1199 /* Parameter for 'simple_stripe' is 8 bytes */
1200 total_len += 8;
1202 issimplestripe = 1;
1205 dist_item = proto_tree_add_string(tree, hf_pvfs_distribution, tvb, offset,
1206 total_len + 8, tmpstr);
1207 dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
1210 /* io_dist */
1211 offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
1212 NULL);
1214 /* TODO: only one distribution type is currently supported */
1215 if (issimplestripe)
1216 offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
1217 hf_pvfs_strip_size, NULL);
1219 offset += 8;
1221 return offset;
1224 static int
1225 dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
1226 packet_info *pinfo)
1228 guint32 dfile_count, i;
1230 /* dfile_count */
1231 dfile_count = tvb_get_letohl(tvb, offset);
1232 proto_tree_add_uint(tree, hf_pvfs_dfile_count, tvb, offset, 4, dfile_count);
1234 offset += 4;
1236 for (i = 0; i < dfile_count; i++)
1237 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1239 return offset;
1242 static int
1243 dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
1244 packet_info *pinfo)
1246 gint32 ds_type = 0;
1247 guint32 attrmask = 0;
1248 proto_item *attr_item;
1249 proto_tree *attr_tree;
1251 attr_item = proto_tree_add_text(tree, tvb, offset, -1, "Attributes");
1252 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr_tree);
1254 /* UID */
1255 proto_tree_add_item(attr_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1256 offset += 4;
1258 /* GID */
1259 proto_tree_add_item(attr_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1260 offset += 4;
1262 /* Permissions */
1263 proto_tree_add_item(attr_tree, hf_pvfs_permissions, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1264 offset += 4;
1266 offset += 4;
1268 /* atime */
1269 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
1270 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1272 /* mtime */
1273 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
1274 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1276 /* ctime */
1277 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
1278 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1280 /* attrmask */
1281 offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
1283 /* objtype */
1284 offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
1286 if (attrmask & PVFS_ATTR_META_DIST)
1288 offset = dissect_pvfs_distribution(tvb, attr_tree, offset);
1290 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1292 else
1294 if (attrmask & PVFS_ATTR_META_DFILES)
1296 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1298 else
1300 if (attrmask & PVFS_ATTR_DATA_SIZE)
1302 offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
1303 NULL);
1305 else
1307 if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
1309 /* target_path_len */
1310 proto_tree_add_text(attr_tree, tvb, offset, 4,
1311 "target_path_len: %d", tvb_get_letohl(tvb, offset));
1312 offset += 4;
1314 offset += 4;
1316 /* target_path */
1317 offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
1318 offset, NULL);
1320 else
1322 if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
1324 offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
1325 hf_pvfs_size, NULL);
1332 return offset;
1335 static int
1336 dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1338 proto_tree_add_item(tree, hf_pvfs_io_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1339 offset += 4;
1341 return offset;
1344 static int
1345 dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1347 proto_tree_add_item(tree, hf_pvfs_flowproto_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1348 offset += 4;
1350 return offset;
1353 static int
1354 dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
1355 packet_info *pinfo)
1357 guint32 server_param;
1358 proto_item* ti;
1360 /* server_param */
1361 server_param = tvb_get_letohl(tvb, offset);
1362 proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
1363 server_param);
1364 offset += 4;
1366 switch (server_param)
1368 case PVFS_SERV_PARAM_MODE:
1369 ti = proto_tree_add_item(tree, hf_pvfs_server_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1370 proto_item_set_len(ti, 8);
1371 break;
1373 case PVFS_SERV_PARAM_FSID_CHECK:
1374 proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1375 proto_tree_add_item(tree, hf_pvfs_unused, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1376 break;
1378 case PVFS_SERV_PARAM_ROOT_CHECK:
1379 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1380 break;
1383 offset += 8;
1385 return offset;
1388 static int
1389 dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1391 proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1392 offset += 4;
1394 return offset;
1398 * =======================================================================
1399 * Request handlers
1400 * =======================================================================
1403 static int
1404 dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1405 packet_info *pinfo)
1407 /* fs_id */
1408 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1410 /* type */
1411 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
1413 offset += 4;
1415 offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
1417 return offset;
1420 static int
1421 dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1422 packet_info *pinfo)
1424 /* handle */
1425 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1427 /* fs_id */
1428 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1430 return offset;
1433 static int
1434 dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
1436 /* offset */
1437 proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1438 offset += 8;
1440 /* TODO: num_eregs */
1441 proto_tree_add_item(tree, hf_pvfs_num_eregs, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1442 offset += 4;
1444 /* TODO: num_blocks */
1445 proto_tree_add_item(tree, hf_pvfs_num_blocks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1446 offset += 4;
1448 /* TODO: stride */
1449 proto_tree_add_item(tree, hf_pvfs_stride, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1450 offset += 8;
1452 /* TODO: ub */
1453 proto_tree_add_item(tree, hf_pvfs_ub, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1454 offset += 8;
1456 /* TODO: lb */
1457 proto_tree_add_item(tree, hf_pvfs_lb, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1458 offset += 8;
1460 /* TODO: aggregate size */
1461 proto_tree_add_item(tree, hf_pvfs_aggregate_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1462 offset += 8;
1464 /* num_contig_chunks */
1465 proto_tree_add_item(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1466 offset += 4;
1468 /* depth */
1469 proto_tree_add_item(tree, hf_pvfs_depth, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1470 offset += 4;
1472 /* num_nested_req */
1473 proto_tree_add_item(tree, hf_pvfs_num_nested_req, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1474 offset += 4;
1476 /* committed */
1477 proto_tree_add_item(tree, hf_pvfs_committed, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1478 offset += 4;
1480 /* refcount */
1481 proto_tree_add_item(tree, hf_pvfs_refcount, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1482 offset += 4;
1484 /* documented */
1485 offset += 4;
1487 /* ereg */
1488 proto_tree_add_item(tree, hf_pvfs_ereg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1489 offset += 4;
1491 /* sreg */
1492 proto_tree_add_item(tree, hf_pvfs_sreg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1493 offset += 4;
1495 return offset;
1498 static int
1499 dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1500 packet_info *pinfo)
1502 /* handle */
1503 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1505 /* fs_id */
1506 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1508 /* skip4 as per source code */
1509 offset += 4;
1511 /* io_type */
1512 offset = dissect_pvfs_io_type(tvb, tree, offset);
1514 /* flow_type */
1515 offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
1517 /* server_nr */
1518 proto_tree_add_item(tree, hf_pvfs_server_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1519 offset += 4;
1521 /* server_ct */
1522 proto_tree_add_item(tree, hf_pvfs_server_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1523 offset += 4;
1525 /* Distribution */
1526 offset = dissect_pvfs_distribution(tvb, tree, offset);
1528 proto_tree_add_item(tree, hf_pvfs_numreq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1529 offset += 4;
1531 /* */
1532 offset += 4;
1534 /*offset = */dissect_pvfs_pint_request(tvb, tree, offset);
1536 /* TODO: remove this!!! */
1537 offset = tvb_length(tvb) - 16;
1539 /* offset */
1540 proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1541 offset += 8;
1543 /* size */
1544 proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1545 offset += 8;
1547 return offset;
1550 static int
1551 dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1552 packet_info *pinfo)
1554 /* handle */
1555 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1557 /* fs_id */
1558 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1560 /* attrmask */
1561 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1563 return offset;
1566 static int
1567 dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1568 packet_info *pinfo)
1570 /* handle */
1571 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1573 /* parent_ref: fs_id */
1574 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1576 offset += 4;
1578 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1580 return offset;
1583 /* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
1584 static int
1585 dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
1586 int offset, packet_info *pinfo)
1588 /* Path */
1589 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1591 /* fs_id */
1592 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1594 offset += 4;
1596 /* starting_handle */
1597 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1599 /* attribute mask */
1600 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1602 return offset;
1605 static int
1606 dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1607 packet_info *pinfo)
1609 /* Filename */
1610 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1612 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
1614 /* parent_handle */
1615 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1617 /* fs_id */
1618 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1620 offset += 4;
1622 /* atime */
1623 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1624 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1626 /* mtime */
1627 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1628 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1630 /* ctime */
1631 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1632 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1634 return offset;
1637 /* TODO: incomplete */
1638 static int
1639 dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1640 packet_info *pinfo)
1642 /* path */
1643 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1645 /* handle */
1646 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1648 /* fs_id */
1649 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1651 offset += 4;
1653 /* atime */
1654 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1655 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1657 /* mtime */
1658 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1659 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1661 /* ctime */
1662 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1663 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1665 return offset;
1668 static int
1669 dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1670 packet_info *pinfo)
1672 /* path */
1673 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1675 /* New directory entry handle */
1676 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
1677 NULL);
1679 /* Parent handle */
1680 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1682 /* fs_id */
1683 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1685 /* Parent atime */
1686 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
1687 hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
1689 /* Parent mtime */
1690 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
1691 hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
1693 /* Parent ctime */
1694 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
1695 hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
1697 return offset;
1700 static int
1701 dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1702 packet_info *pinfo)
1704 /* handle */
1705 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1707 /* fs_id */
1708 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1710 offset += 4;
1712 /* size */
1713 proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1714 offset += 8;
1716 /* TODO: flags */
1717 proto_tree_add_item(tree, hf_pvfs_truncate_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1718 offset += 4;
1720 return offset;
1723 static int
1724 dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1725 packet_info *pinfo)
1727 guint count, i;
1729 /* fs_id */
1730 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1732 offset += 4;
1734 /* attr */
1735 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1737 /* handle_extent_array */
1738 count = tvb_get_letohl(tvb, offset);
1739 offset += 4;
1741 for (i = 0; i < count; i++)
1742 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1744 return offset;
1747 static int
1748 dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1749 packet_info *pinfo)
1751 /* object_ref: handle */
1752 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1754 /* object_ref: fs_id */
1755 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1757 /* ds_position */
1758 proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1759 offset += 4;
1761 /* dirent_limit */
1762 proto_tree_add_item(tree, hf_pvfs_dirent_limit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1763 offset += 4;
1765 return offset;
1768 static int
1769 dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
1770 int offset, packet_info *pinfo)
1772 /* handle */
1773 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1775 /* fs_id */
1776 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1778 /* flags */
1779 proto_tree_add_item(tree, hf_pvfs_flush_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1780 offset += 4;
1782 return offset;
1785 static int
1786 dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
1787 int offset, packet_info *pinfo)
1789 /* fs_id */
1790 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1792 /* server_param */
1793 offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
1795 return offset;
1798 static int
1799 dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1800 packet_info *pinfo _U_)
1802 /* fs_id */
1803 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1805 return offset;
1808 static int
1809 dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
1810 int offset, packet_info *pinfo _U_)
1812 /* TODO: next_id */
1813 proto_tree_add_item(tree, hf_pvfs_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1814 offset += 4;
1816 /* TODO: count */
1817 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1818 offset += 4;
1820 return offset;
1823 static int
1824 dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
1825 int offset, packet_info *pinfo)
1827 /* fs_id */
1828 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1830 /* handle */
1831 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1833 return offset;
1836 static int
1837 dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
1838 proto_tree *tree, int offset, packet_info *pinfo)
1840 guint32 handle_count, i;
1842 /* fs_id */
1843 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1845 /* handle count */
1846 handle_count = tvb_get_letohl(tvb, offset);
1847 offset += 4;
1849 for (i = 0; i < handle_count; i++)
1851 /* handle */
1852 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1855 return offset;
1858 static int
1859 dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
1860 int offset, packet_info *pinfo _U_)
1862 /* event_count */
1863 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_event_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1864 offset += 4;
1866 return offset;
1869 static int
1870 dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
1871 int offset, packet_info *pinfo)
1873 /* Handle */
1874 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1876 /* fs_id */
1877 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1879 return offset;
1882 static int
1883 dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
1884 proto_tree *tree, int offset, packet_info *pinfo)
1886 /* Handle */
1887 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1889 /* fs_id */
1890 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1892 /* */
1893 offset += 4;
1895 /* entry */
1896 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1898 return offset;
1901 static int
1902 dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
1903 proto_tree *tree, int offset, packet_info *pinfo)
1905 /* Handle */
1906 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1908 /* fs_id */
1909 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1911 return offset;
1914 /* TODO: untested/incomplete */
1915 static int
1916 dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset)
1918 /* attribute key */
1919 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
1920 NULL);
1922 /* attribute value */
1923 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
1924 NULL);
1926 return offset;
1929 /* TODO: incomplete/untested */
1930 static int
1931 dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset)
1933 guint32 nKey, i;
1935 /* number of keys and vals */
1936 nKey = tvb_get_letohl(tvb, offset);
1937 offset += 4;
1939 for (i = 0; i < nKey; i++)
1940 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
1942 return offset;
1945 /* TODO: incomplete/untested */
1946 static int
1947 dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
1948 int offset, packet_info *pinfo)
1950 /* handle */
1951 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1953 /* fs_id */
1954 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1956 offset += 4;
1958 offset = dissect_ds_keyval_array(tvb, tree, offset);
1960 return offset;
1963 /* TODO: incomplete/untested */
1964 static int
1965 dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
1966 int offset, packet_info *pinfo)
1968 /* handle */
1969 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1971 /* fs_id */
1972 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1974 offset += 4;
1976 offset = dissect_ds_keyval_array(tvb, tree, offset);
1978 return offset;
1981 /* TODO: untested */
1982 static int
1983 dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
1984 int offset, packet_info *pinfo)
1986 /* handle */
1987 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1989 /* fs_id */
1990 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1992 /* key */
1993 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
1995 return offset;
1998 static int
1999 dissect_pvfs2_release_number(tvbuff_t *tvb, proto_tree *tree, int offset)
2001 guint32 release_nr = tvb_get_letohl(tvb, offset);
2003 proto_tree_add_text(tree, tvb, offset, 4,
2004 "PVFS2 Release Number: %d (%d.%d.%d)",
2005 release_nr,
2006 release_nr / 10000,
2007 (release_nr % 10000) / 100,
2008 (release_nr % 10000) % 100);
2009 offset += 4;
2011 return offset;
2014 static int
2015 dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
2017 /* PVFS release number */
2018 offset = dissect_pvfs2_release_number(tvb, tree, offset);
2020 /* wire encoding type */
2021 proto_tree_add_item(tree, hf_pvfs_encoding, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2022 offset += 4;
2024 /* server op */
2025 proto_tree_add_item(tree, hf_pvfs_server_op, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2026 offset += 4;
2028 return offset;
2031 static int
2032 dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
2033 packet_info *pinfo, guint32 server_op)
2035 /* context_id */
2036 proto_tree_add_item(tree, hf_pvfs_context_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2037 offset += 4;
2039 /* credentials */
2040 offset = dissect_pvfs_credentials(tvb, tree, offset);
2042 switch (server_op)
2044 case PVFS_SERV_CREATE:
2045 offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
2046 break;
2048 case PVFS_SERV_REMOVE:
2049 offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
2050 break;
2052 case PVFS_SERV_IO:
2053 offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
2054 break;
2056 case PVFS_SERV_GETATTR:
2057 offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
2058 break;
2060 case PVFS_SERV_SETATTR:
2061 offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
2062 break;
2064 case PVFS_SERV_LOOKUP_PATH:
2065 offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
2066 break;
2068 case PVFS_SERV_CRDIRENT:
2069 offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
2070 break;
2072 case PVFS_SERV_RMDIRENT:
2073 offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
2074 break;
2076 case PVFS_SERV_CHDIRENT:
2077 offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
2078 break;
2080 case PVFS_SERV_TRUNCATE:
2081 offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
2082 break;
2084 case PVFS_SERV_MKDIR:
2085 offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
2086 break;
2088 case PVFS_SERV_READDIR:
2089 offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
2090 break;
2092 #if 0
2093 case PVFS_SERV_GETCONFIG:
2094 /* No parameters in request */
2095 break;
2096 #endif
2098 #if 0
2099 case PVFS_SERV_WRITE_COMPLETION:
2100 /* No parameters in request */
2101 break;
2102 #endif
2104 case PVFS_SERV_FLUSH:
2105 offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
2106 break;
2108 case PVFS_SERV_MGMT_SETPARAM:
2109 offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
2110 pinfo);
2111 break;
2113 #if 0
2114 case PVFS_SERV_MGMT_NOOP:
2115 /* No parameters in request */
2116 break;
2117 #endif
2119 case PVFS_SERV_STATFS:
2120 offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
2121 break;
2123 #if 0
2124 case PVFS_SERV_PERF_UPDATE:
2125 /* No parameters in request */
2126 break;
2127 #endif
2129 case PVFS_SERV_MGMT_PERF_MON:
2130 offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
2131 pinfo);
2132 break;
2134 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2135 offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
2136 offset, pinfo);
2137 break;
2139 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2140 offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
2141 offset, pinfo);
2142 break;
2144 case PVFS_SERV_MGMT_EVENT_MON:
2145 offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
2146 pinfo);
2147 break;
2149 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2150 offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
2151 pinfo);
2152 break;
2154 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2155 offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
2156 pinfo);
2157 break;
2159 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2160 offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
2161 offset, pinfo);
2162 break;
2164 #if 0
2165 case PVFS_SERV_JOB_TIMER:
2166 /* No parameters in request */
2167 break;
2168 #endif
2170 case PVFS_SERV_PROTO_ERROR:
2171 /* TODO: is this necessary? */
2172 break;
2174 case PVFS_SERV_GETEATTR:
2175 offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
2176 break;
2178 case PVFS_SERV_SETEATTR:
2179 offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
2180 break;
2182 case PVFS_SERV_DELEATTR:
2183 offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
2184 break;
2186 default:
2187 /* TODO: what should we do here? */
2188 break;
2191 return offset;
2195 * =======================================================================
2196 * Response handlers
2197 * =======================================================================
2200 static int
2201 dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2202 packet_info *pinfo)
2204 /* Handle */
2205 return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2208 static int
2209 dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2211 return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
2214 static int
2215 dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
2216 int offset, packet_info *pinfo)
2218 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
2220 return offset;
2223 static int
2224 dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
2225 int offset, packet_info *pinfo)
2227 guint32 nCount = 0;
2228 guint32 handle_count = 0;
2229 guint32 attr_count = 0;
2230 proto_item *attr_item = NULL;
2231 proto_tree *attr_tree = NULL;
2233 offset += 4;
2235 /* handle_count */
2236 handle_count = tvb_get_letohl(tvb, offset);
2237 proto_tree_add_item(tree, hf_pvfs_lookup_path_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2238 offset += 4;
2240 /* TODO: add bounds checking */
2241 for (nCount = 0; nCount < handle_count; nCount++)
2242 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2244 offset += 4;
2246 /* array of attributes */
2247 attr_count = tvb_get_letohl(tvb, offset);
2249 if (tree)
2251 attr_item = proto_tree_add_text(tree, tvb, offset, 4,
2252 "Attribute array (total items: %d)", attr_count);
2254 if (attr_item)
2255 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr);
2258 offset += 4;
2260 /* Array of attributes */
2261 for (nCount = 0; nCount < attr_count; nCount++)
2262 offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
2264 return offset;
2267 static int
2268 dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2269 packet_info *pinfo)
2271 /* Handle */
2272 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2274 return offset;
2277 static int
2278 dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2279 packet_info *pinfo)
2281 /* Handle */
2282 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2284 return offset;
2287 static int
2288 dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2289 packet_info *pinfo)
2291 /* Handle */
2292 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2294 return offset;
2297 static int
2298 dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2299 packet_info *pinfo)
2301 guint32 dirent_count = 0;
2302 guint32 nCount = 0;
2304 /* ds_position */
2305 proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2306 offset += 4;
2308 offset += 4;
2310 /* directory_version */
2311 proto_tree_add_item(tree, hf_pvfs_directory_version, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2312 offset += 8;
2314 offset += 4;
2316 /* dirent_count */
2317 dirent_count = tvb_get_letohl(tvb, offset);
2318 proto_tree_add_item(tree, hf_pvfs_dirent_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2319 offset += 4;
2321 for (nCount = 0; nCount < dirent_count; nCount++)
2323 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
2324 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2327 return offset;
2331 * TODO: this code needs work! Not finished yet!
2333 static int
2334 dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
2335 int offset)
2337 guint32 i;
2338 guint32 total_bytes = 0, total_config_bytes = 0, total_lines = 0;
2339 guint32 bytes_processed = 0;
2340 guint32 length_remaining = 0;
2341 char *ptr = NULL;
2342 proto_item *item = NULL, *config_item = NULL;
2343 proto_tree *tree = NULL, *config_tree = NULL;
2344 /*guint8 truncated = 0;*/
2346 if (parent_tree)
2348 item = proto_tree_add_text(parent_tree, tvb, offset, 12,
2349 "Server Config");
2351 if (item)
2352 tree = proto_item_add_subtree(item, ett_pvfs_server_config);
2355 /* Total number of bytes in server config (incl. entry count) */
2356 total_bytes = tvb_get_letohl(tvb, offset);
2357 proto_tree_add_item(tree, hf_pvfs_getconfig_response_total_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2358 offset += 4;
2360 /* There must be at least 4 bytes of data returned to determine the
2361 * size of the server config data
2363 if (total_bytes < 4)
2365 /* Server config not returned, bail out */
2366 return offset;
2369 /* Number of entries in server config */
2370 total_lines = tvb_get_letohl(tvb, offset);
2371 proto_tree_add_item(tree, hf_pvfs_getconfig_response_lines, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2372 offset += 4;
2374 /* Number of bytes in server config */
2375 total_config_bytes = tvb_get_letohl(tvb, offset);
2376 proto_tree_add_item(tree, hf_pvfs_getconfig_response_config_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2377 offset += 4;
2379 /* Get pointer to server config data */
2380 ptr = (char *) tvb_get_ptr(tvb, offset, total_config_bytes);
2382 /* Check if all data is available */
2383 length_remaining = tvb_length_remaining(tvb, offset);
2385 if (length_remaining < total_config_bytes)
2387 total_config_bytes = length_remaining;
2389 /*truncated = 1;*/
2392 bytes_processed = 0;
2394 for (i = 0; i < total_lines; i++)
2396 guint8 entry[256], *pentry = entry, *tmp_entry = NULL;
2397 guint32 entry_length = 0, tmp_entry_length = 0;
2398 guint32 bufsiz = sizeof(entry);
2400 while ((*ptr != '\n') && (*ptr != '\0') &&
2401 (bytes_processed < total_config_bytes) &&
2402 (entry_length < bufsiz))
2404 *pentry++ = *ptr++;
2406 bytes_processed++;
2407 entry_length++;
2410 if ((entry_length == bufsiz) &&
2411 ((entry[entry_length - 1] != '\n') &&
2412 (entry[entry_length - 1] != '\0')))
2415 * Single line of config data doesn't fit into provided buffer,
2416 * config data is malformed.
2419 break;
2422 if (bytes_processed == total_config_bytes)
2424 /* Oops... ran out of data before we could complete the entry */
2425 break;
2428 *pentry= '\0';
2430 tmp_entry = entry;
2431 tmp_entry_length = entry_length;
2433 /* Remove all whitespace from front of entry */
2434 while ((tmp_entry_length > 0) && (!isalnum(*tmp_entry)) &&
2435 (*tmp_entry != '<'))
2437 tmp_entry++;
2438 tmp_entry_length--;
2441 if (tmp_entry[0] == '<')
2443 if (tmp_entry[tmp_entry_length - 1] == '>')
2445 /* Token */
2446 if (tmp_entry[1] != '/')
2448 /* Opening token, create new tree root */
2449 config_item = proto_tree_add_text(tree, tvb, offset,
2450 tmp_entry_length, "%s", tmp_entry);
2452 if (config_item)
2453 config_tree = proto_item_add_subtree(config_item,
2454 ett_pvfs_server_config_branch);
2456 else
2458 /* Closing token */
2459 config_item = NULL;
2460 config_tree = NULL;
2463 else
2465 /* Malformed token */
2466 break;
2469 else
2471 /* Insert items into the root config tree if there's no subtree
2472 * defined.
2474 if (config_tree == NULL)
2475 config_tree = tree;
2477 if (tmp_entry_length > 0)
2479 proto_tree_add_text(config_tree, tvb, offset, tmp_entry_length,
2480 "%s", tmp_entry);
2484 offset += entry_length + 1;
2486 ptr++;
2487 bytes_processed++;
2490 if (bytes_processed < total_config_bytes)
2492 /* We ran out of server config data */
2493 proto_tree_add_text(config_tree, tvb, offset, -1,
2494 "<MALFORMED OR TRUNCATED DATA>");
2497 return offset;
2500 static int
2501 dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
2502 int offset)
2504 /* size */
2505 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
2506 NULL);
2508 return offset;
2511 static int
2512 dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
2513 int offset)
2515 /* old_value */
2516 proto_tree_add_item(tree, hf_pvfs_prev_value, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2518 offset += 8;
2520 return offset;
2523 static int
2524 dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2526 offset += 4;
2528 /* fs_id */
2529 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2531 /* bytes_available */
2532 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
2533 NULL);
2535 /* bytes_total */
2536 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
2537 NULL);
2539 /* RAM bytes total */
2540 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
2541 NULL);
2543 /* RAM bytes free */
2544 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
2545 NULL);
2547 /* load average (1s) */
2548 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
2549 NULL);
2551 /* load average (5s) */
2552 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
2553 NULL);
2555 /* load average (15s) */
2556 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
2557 NULL);
2559 /* uptime (seconds) */
2560 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
2561 NULL);
2563 /* handles_available_count */
2564 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
2565 NULL);
2567 /* handles_total_count */
2568 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
2569 NULL);
2571 return offset;
2574 static int
2575 dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
2576 int nItem)
2578 proto_item *stat_item = NULL;
2579 proto_tree *stat_tree = NULL;
2581 if (tree)
2583 stat_item = proto_tree_add_text(tree, tvb, offset, 48,
2584 "Stat Array - Element %d", nItem);
2586 if (stat_item)
2587 stat_tree = proto_item_add_subtree(stat_item,
2588 ett_pvfs_mgmt_perf_stat);
2591 /* TODO: valid_flag */
2592 proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_valid_flag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2593 offset += 4;
2595 /* TODO: id */
2596 proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2597 offset += 4;
2599 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
2600 NULL);
2601 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
2602 NULL);
2603 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
2604 NULL);
2605 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
2606 NULL);
2607 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
2608 NULL);
2610 return offset;
2613 static int
2614 dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
2615 int offset)
2617 guint32 perf_array_count, i;
2619 /* TODO: suggested_next_id */
2620 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_response_suggested_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2621 offset += 4;
2623 offset += 4;
2625 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms, NULL);
2626 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms, NULL);
2628 offset += 4;
2630 /* TODO: perf_array_count */
2631 perf_array_count = tvb_get_letohl(tvb, offset);
2632 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_response_perf_array_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2633 offset += 4;
2635 for (i = 0; i < perf_array_count; i++)
2636 offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
2638 return offset;
2641 static int
2642 dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
2643 int offset, packet_info *pinfo)
2645 guint32 handle_count, i;
2647 /* ds_position */
2648 proto_tree_add_item(tree, hf_pvfs_mgmt_iterate_handles_response_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2649 offset += 4;
2651 /* handle_count */
2652 handle_count = tvb_get_letohl(tvb, offset);
2653 proto_tree_add_item(tree, hf_pvfs_mgmt_iterate_handles_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2654 offset += 4;
2656 /* TODO: this could be improved */
2657 for (i = 0; i < handle_count; i++)
2658 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2660 return offset;
2663 static int
2664 dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
2665 packet_info *pinfo)
2667 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2668 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2669 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
2670 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
2671 NULL);
2672 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
2673 NULL);
2674 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2676 return offset;
2679 static int
2680 dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
2681 int offset, packet_info *pinfo)
2683 guint32 dspace_info_count, i;
2684 proto_item *arr_item = NULL;
2685 proto_tree *arr_tree = NULL;
2687 offset += 4;
2689 /* dspace_info_count */
2690 dspace_info_count = tvb_get_letohl(tvb, offset);
2691 proto_tree_add_item(tree, hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2693 if ((dspace_info_count > 0) && (tree))
2695 arr_item = proto_tree_add_text(tree, tvb, offset,
2696 dspace_info_count * 40, "dspace_info Array (%d items)",
2697 dspace_info_count);
2699 if (arr_item)
2700 arr_tree = proto_item_add_subtree(arr_item,
2701 ett_pvfs_mgmt_dspace_info);
2704 for (i = 0; i < dspace_info_count; i++)
2705 offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
2707 return offset;
2710 static int
2711 dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
2712 int offset)
2714 /* api */
2715 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_api, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2716 offset += 4;
2718 /* operation */
2719 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_operation, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2720 offset += 4;
2722 /* value */
2723 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_value, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2724 offset += 4;
2726 /* id */
2727 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
2728 NULL);
2730 /* flags */
2731 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2732 offset += 4;
2734 /* tv_sec */
2735 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_sec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2736 offset += 4;
2738 /* tv_usec */
2739 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_usec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2740 offset += 4;
2742 offset += 4;
2744 return offset;
2747 static int
2748 dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
2749 int offset, packet_info *pinfo)
2751 /* handle */
2752 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2754 /* fs_id */
2755 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2757 return offset;
2760 static int
2761 dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
2762 proto_tree *tree, int offset, packet_info *pinfo)
2764 /* handle */
2765 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2767 return offset;
2770 /* TODO: untested */
2771 static int
2772 dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2773 packet_info *pinfo _U_)
2775 offset += 4;
2777 /* Dissect nKey & ds_keyval array */
2778 offset = dissect_ds_keyval_array(tvb, tree, offset);
2780 return offset;
2783 static int
2784 dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2785 packet_info *pinfo, guint32 server_op)
2787 /* error code */
2788 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2790 switch (server_op)
2792 case PVFS_SERV_CREATE:
2793 offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
2794 break;
2796 #if 0
2797 case PVFS_SERV_REMOVE:
2798 /* No result data */
2799 break;
2800 #endif
2802 case PVFS_SERV_IO:
2803 offset = dissect_pvfs2_io_response(tvb, tree, offset);
2804 break;
2806 case PVFS_SERV_GETATTR:
2807 offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
2808 break;
2810 case PVFS_SERV_SETATTR:
2811 /* No result data */
2812 break;
2814 case PVFS_SERV_LOOKUP_PATH:
2815 offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
2816 break;
2818 #if 0
2819 case PVFS_SERV_CRDIRENT:
2820 /* No result data */
2821 break;
2822 #endif
2824 case PVFS_SERV_RMDIRENT:
2825 offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
2826 break;
2828 case PVFS_SERV_CHDIRENT:
2829 offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
2830 break;
2832 #if 0
2833 case PVFS_SERV_TRUNCATE:
2834 /* No result data */
2835 break;
2836 #endif
2838 case PVFS_SERV_MKDIR:
2839 offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
2840 break;
2842 case PVFS_SERV_READDIR:
2843 offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
2844 break;
2846 case PVFS_SERV_GETCONFIG:
2847 offset = dissect_pvfs2_getconfig_response(tvb, tree, offset);
2848 break;
2850 case PVFS_SERV_WRITE_COMPLETION:
2851 offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
2852 break;
2854 #if 0
2855 case PVFS_SERV_FLUSH:
2856 /* No result data */
2857 break;
2858 #endif
2860 case PVFS_SERV_MGMT_SETPARAM:
2861 offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
2862 break;
2864 #if 0
2865 case PVFS_SERV_MGMT_NOOP:
2866 /* No result data */
2867 break;
2868 #endif
2870 case PVFS_SERV_STATFS:
2871 offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
2872 break;
2874 #if 0
2875 case PVFS_SERV_PERF_UPDATE:
2876 /* No result data */
2877 break;
2878 #endif
2880 case PVFS_SERV_MGMT_PERF_MON:
2881 offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
2882 break;
2884 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2885 offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
2886 offset, pinfo);
2887 break;
2889 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2890 offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
2891 offset, pinfo);
2892 break;
2894 case PVFS_SERV_MGMT_EVENT_MON:
2895 offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
2896 break;
2898 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2899 offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
2900 pinfo);
2901 break;
2903 #if 0
2904 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2905 /* No result data */
2906 break;
2907 #endif
2909 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2910 offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
2911 offset, pinfo);
2912 break;
2914 #if 0
2915 case PVFS_SERV_JOB_TIMER:
2916 /* No result data */
2917 break;
2918 #endif
2920 case PVFS_SERV_PROTO_ERROR:
2921 /* No result data */
2922 break;
2924 /* TODO: untested */
2925 case PVFS_SERV_GETEATTR:
2926 offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
2927 break;
2929 #if 0
2930 case PVFS_SERV_SETEATTR:
2931 /* No result data */
2932 break;
2933 #endif
2935 #if 0
2936 case PVFS_SERV_DELEATTR:
2937 /* No result data */
2938 break;
2939 #endif
2941 default:
2942 /* TODO: what do we do here? */
2943 break;
2946 return offset;
2949 static GHashTable *pvfs2_io_tracking_value_table = NULL;
2951 typedef struct pvfs2_io_tracking_key
2953 guint64 tag;
2954 } pvfs2_io_tracking_key_t;
2956 typedef struct pvfs2_io_tracking_value
2958 guint32 request_frame_num;
2959 guint32 response_frame_num;
2960 guint32 flow_frame_num;
2962 } pvfs2_io_tracking_value_t;
2964 static gint
2965 pvfs2_io_tracking_equal(gconstpointer k1, gconstpointer k2)
2967 const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
2968 const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
2970 return (key1->tag == key2->tag);
2973 static guint
2974 pvfs2_io_tracking_hash(gconstpointer k)
2976 const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
2978 return (guint) ((key->tag >> 32) ^ ((guint32) key->tag));
2981 static void
2982 pvfs2_io_tracking_init(void)
2984 if (pvfs2_io_tracking_value_table != NULL)
2985 g_hash_table_destroy(pvfs2_io_tracking_value_table);
2987 pvfs2_io_tracking_value_table = g_hash_table_new(pvfs2_io_tracking_hash,
2988 pvfs2_io_tracking_equal);
2991 static pvfs2_io_tracking_value_t *
2992 pvfs2_io_tracking_new_with_tag(guint64 tag, guint32 num)
2994 pvfs2_io_tracking_value_t *value;
2995 pvfs2_io_tracking_key_t *newkey;
2997 newkey = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_key_t);
2998 newkey->tag = tag;
3000 value = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_value_t);
3002 g_hash_table_insert(pvfs2_io_tracking_value_table, newkey, value);
3004 value->request_frame_num = num;
3006 return value;
3009 static gboolean
3010 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
3011 gboolean dissect_other_as_continuation _U_)
3013 guint32 mode = 0;
3014 proto_item *item = NULL, *hitem = NULL;
3015 proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
3016 int offset = 0;
3017 guint64 tag;
3018 guint32 server_op;
3019 pvfs2_io_tracking_value_t *val = NULL;
3021 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
3023 col_clear(pinfo->cinfo, COL_INFO);
3025 if (parent_tree)
3027 item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, ENC_NA);
3029 if (item)
3030 pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
3033 proto_tree_add_text(pvfs_tree, tvb, 0, -1, "Version: 2");
3035 /* PVFS packet header is 24 bytes */
3036 hitem = proto_tree_add_text(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
3037 "BMI Header");
3038 if (hitem)
3039 pvfs_htree = proto_item_add_subtree(hitem, ett_pvfs_hdr);
3041 /* Magic number */
3042 proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3043 offset += 4;
3045 /* TCP message mode (32-bit) */
3046 mode = tvb_get_letohl(tvb, offset);
3047 proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
3048 offset += 4;
3050 /* tag (64-bit) */
3051 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
3053 /* size (64-bit) */
3054 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
3056 /* Lookahead to get server_op (invalid if frame contains flow data) */
3057 server_op = tvb_get_letohl(tvb, offset + 8);
3059 if (mode == TCP_MODE_UNEXP)
3061 /* Add entry to tracking table for PVFS_SERV_IO request */
3062 if ((server_op == PVFS_SERV_IO) && !pinfo->fd->flags.visited)
3063 val = pvfs2_io_tracking_new_with_tag(tag, pinfo->fd->num);
3065 else
3067 pvfs2_io_tracking_key_t key;
3069 memset(&key, 0, sizeof(key));
3070 key.tag = tag;
3072 val = (pvfs2_io_tracking_value_t *)g_hash_table_lookup(pvfs2_io_tracking_value_table, &key);
3074 /* If this frame contains a known PVFS_SERV_IO tag, track it */
3075 if (val && !pinfo->fd->flags.visited)
3077 /* If response HAS NOT been seen, mark this frame as response */
3078 if (val->response_frame_num == 0)
3079 val->response_frame_num = pinfo->fd->num;
3080 else
3082 /* If response HAS been seen, this frame is flow data */
3083 if (val->flow_frame_num == 0)
3084 val->flow_frame_num = pinfo->fd->num;
3089 if (val && (val->flow_frame_num == pinfo->fd->num))
3091 /* This frame is marked as being flow data */
3092 col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
3094 proto_tree_add_text(pvfs_tree, tvb, offset, -1, "<data>");
3096 return TRUE;
3099 /* Extract common part of packet found in requests and responses */
3100 offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
3102 /* Update column info display */
3103 col_add_str(pinfo->cinfo, COL_INFO,
3104 val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
3106 col_append_str(pinfo->cinfo, COL_INFO,
3107 (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
3109 /* TODO: handle all modes */
3110 if (mode == TCP_MODE_UNEXP)
3112 /* Request */
3113 /*offset = */dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
3115 else
3117 /* TODO: re-examine this! */
3118 #if 0
3119 if (mode == TCP_MODE_REND)
3122 * TODO: move this code outside so it's common for requests and
3123 * responses
3126 col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
3128 else
3129 #endif
3131 /* Response */
3132 /*offset = */dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
3133 server_op);
3137 return TRUE;
3140 /* Register the protocol with Wireshark */
3141 void
3142 proto_register_pvfs(void)
3144 static hf_register_info hf[] = {
3145 { &hf_pvfs_magic_nr,
3146 { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
3147 NULL, 0, NULL, HFILL }},
3149 { &hf_pvfs_uid,
3150 { "UID", "pvfs.uid", FT_UINT32, BASE_DEC,
3151 NULL, 0, NULL, HFILL }},
3153 { &hf_pvfs_gid,
3154 { "GID", "pvfs.gid", FT_UINT32, BASE_DEC,
3155 NULL, 0, NULL, HFILL }},
3157 { &hf_pvfs_mode,
3158 { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
3159 VALS(names_pvfs_mode), 0, NULL, HFILL }},
3161 { &hf_pvfs_tag,
3162 { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
3163 NULL, 0, NULL, HFILL }},
3165 { &hf_pvfs_size,
3166 { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
3167 NULL, 0, NULL, HFILL }},
3169 #if 0
3170 { &hf_pvfs_release_number,
3171 { "Release Number", "pvfs.release_number", FT_UINT32, BASE_DEC,
3172 NULL, 0, NULL, HFILL }},
3173 #endif
3175 { &hf_pvfs_encoding,
3176 { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
3177 VALS(names_pvfs_encoding), 0, NULL, HFILL }},
3179 { &hf_pvfs_server_op,
3180 { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
3181 VALS(names_pvfs_server_op), 0, NULL, HFILL }},
3183 #if 0
3184 { &hf_pvfs_handle,
3185 { "Handle", "pvfs.handle", FT_BYTES, BASE_NONE,
3186 NULL, 0, NULL, HFILL }},
3187 #endif
3189 { &hf_pvfs_fs_id,
3190 { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
3191 NULL, 0, "File System ID", HFILL }},
3193 { &hf_pvfs_attrmask,
3194 { "Attribute Mask", "pvfs.attrmask", FT_UINT32, BASE_DEC,
3195 NULL, 0, NULL, HFILL }},
3197 { &hf_pvfs_attr,
3198 { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
3199 VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
3201 { &hf_pvfs_ds_type,
3202 { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
3203 VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
3205 { &hf_pvfs_error,
3206 { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
3207 VALS(names_pvfs_error), 0, NULL, HFILL }},
3209 { &hf_pvfs_atime,
3210 { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3211 NULL, 0, "Access Time", HFILL }},
3213 { &hf_pvfs_atime_sec,
3214 { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
3215 NULL, 0, "Access Time (seconds)", HFILL }},
3217 { &hf_pvfs_atime_nsec,
3218 { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
3219 NULL, 0, "Access Time (microseconds)", HFILL }},
3221 { &hf_pvfs_mtime,
3222 { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3223 NULL, 0, "Modify Time", HFILL }},
3225 { &hf_pvfs_mtime_sec,
3226 { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
3227 NULL, 0, "Modify Time (seconds)", HFILL }},
3229 { &hf_pvfs_mtime_nsec,
3230 { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
3231 NULL, 0, "Modify Time (microseconds)", HFILL }},
3233 { &hf_pvfs_ctime,
3234 { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3235 NULL, 0, "Creation Time", HFILL }},
3237 { &hf_pvfs_ctime_sec,
3238 { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
3239 NULL, 0, "Creation Time (seconds)", HFILL }},
3241 { &hf_pvfs_ctime_nsec,
3242 { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
3243 NULL, 0, "Creation Time (microseconds)", HFILL }},
3245 { &hf_pvfs_parent_atime,
3246 { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3247 NULL, 0, "Access Time", HFILL }},
3249 { &hf_pvfs_parent_atime_sec,
3250 { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
3251 NULL, 0, "Access Time (seconds)", HFILL }},
3253 { &hf_pvfs_parent_atime_nsec,
3254 { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
3255 NULL, 0, "Access Time (microseconds)", HFILL }},
3257 { &hf_pvfs_parent_mtime,
3258 { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3259 NULL, 0, "Modify Time", HFILL }},
3261 { &hf_pvfs_parent_mtime_sec,
3262 { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
3263 NULL, 0, "Modify Time (seconds)", HFILL }},
3265 { &hf_pvfs_parent_mtime_nsec,
3266 { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
3267 NULL, 0, "Modify Time (microseconds)", HFILL }},
3269 { &hf_pvfs_parent_ctime,
3270 { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3271 NULL, 0, "Creation Time", HFILL }},
3273 { &hf_pvfs_parent_ctime_sec,
3274 { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
3275 NULL, 0, "Creation Time (seconds)", HFILL }},
3277 { &hf_pvfs_parent_ctime_nsec,
3278 { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
3279 NULL, 0, "Creation Time (microseconds)", HFILL }},
3281 { &hf_pvfs_dfile_count,
3282 { "dfile_count", "pvfs.dfile_count", FT_UINT32, BASE_DEC,
3283 NULL, 0, NULL, HFILL }},
3285 { &hf_pvfs_distribution,
3286 { "Distribution", "pvfs.distribution", FT_STRING, BASE_NONE,
3287 NULL, 0, NULL, HFILL }},
3289 { &hf_pvfs_dirent_count,
3290 { "Dir Entry Count", "pvfs.dirent_count", FT_UINT32, BASE_DEC,
3291 NULL, 0, "Directory Entry Count", HFILL }},
3293 { &hf_pvfs_directory_version,
3294 { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
3295 NULL, 0, NULL, HFILL }},
3297 { &hf_pvfs_path,
3298 { "Path", "pvfs.path", FT_STRING, BASE_NONE,
3299 NULL, 0, NULL, HFILL }},
3301 { &hf_pvfs_total_completed,
3302 { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
3303 NULL, 0, NULL, HFILL }},
3305 { &hf_pvfs_io_dist,
3306 { "Name", "pvfs.distribution.name", FT_STRING, BASE_NONE,
3307 NULL, 0, "Distribution Name", HFILL }},
3309 { &hf_pvfs_aggregate_size,
3310 { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
3311 NULL, 0, NULL, HFILL }},
3313 { &hf_pvfs_io_type,
3314 { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
3315 VALS(names_pvfs_io_type), 0, NULL, HFILL }},
3317 { &hf_pvfs_flowproto_type,
3318 { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
3319 VALS(names_pvfs_flowproto_type), 0, NULL, HFILL }},
3321 { &hf_pvfs_server_param,
3322 { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
3323 VALS(names_pvfs_server_param), 0, NULL, HFILL }},
3325 { &hf_pvfs_prev_value,
3326 { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
3327 NULL, 0, NULL, HFILL }},
3329 #if 0
3330 { &hf_pvfs_ram_free_bytes,
3331 { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
3332 NULL, 0, NULL, HFILL }},
3333 #endif
3335 { &hf_pvfs_bytes_available,
3336 { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
3337 NULL, 0, NULL, HFILL }},
3339 { &hf_pvfs_bytes_total,
3340 { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
3341 NULL, 0, NULL, HFILL }},
3343 { &hf_pvfs_ram_bytes_total,
3344 { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
3345 NULL, 0, NULL, HFILL }},
3347 { &hf_pvfs_ram_bytes_free,
3348 { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
3349 NULL, 0, NULL, HFILL }},
3351 { &hf_pvfs_load_average_1s,
3352 { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
3353 NULL, 0, NULL, HFILL }},
3355 { &hf_pvfs_load_average_5s,
3356 { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
3357 NULL, 0, NULL, HFILL }},
3359 { &hf_pvfs_load_average_15s,
3360 { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
3361 NULL, 0, NULL, HFILL }},
3363 { &hf_pvfs_uptime_seconds,
3364 { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
3365 NULL, 0, NULL, HFILL }},
3367 { &hf_pvfs_handles_available,
3368 { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
3369 NULL, 0, NULL, HFILL }},
3371 { &hf_pvfs_handles_total,
3372 { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
3373 NULL, 0, NULL, HFILL }},
3376 * This is used when the field returns 64-bits but we're only interested
3377 * in the lower 32-bit bits.
3379 { &hf_pvfs_unused,
3380 { "Unused", "pvfs.unused", FT_UINT32, BASE_DEC,
3381 NULL, 0, NULL, HFILL }},
3383 { &hf_pvfs_context_id,
3384 { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
3385 NULL, 0, NULL, HFILL }},
3387 { &hf_pvfs_offset,
3388 { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
3389 NULL, 0, NULL, HFILL }},
3391 { &hf_pvfs_stride,
3392 { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
3393 NULL, 0, NULL, HFILL }},
3395 { &hf_pvfs_ub,
3396 { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
3397 NULL, 0, NULL, HFILL }},
3399 { &hf_pvfs_lb,
3400 { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
3401 NULL, 0, NULL, HFILL }},
3403 { &hf_pvfs_end_time_ms,
3404 { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
3405 NULL, 0, NULL, HFILL }},
3407 { &hf_pvfs_cur_time_ms,
3408 { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
3409 NULL, 0, NULL, HFILL }},
3411 { &hf_pvfs_start_time_ms,
3412 { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
3413 NULL, 0, NULL, HFILL }},
3415 { &hf_pvfs_bytes_written,
3416 { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
3417 NULL, 0, NULL, HFILL }},
3419 { &hf_pvfs_bytes_read,
3420 { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
3421 NULL, 0, NULL, HFILL }},
3423 { &hf_pvfs_metadata_write,
3424 { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
3425 NULL, 0, NULL, HFILL }},
3427 { &hf_pvfs_metadata_read,
3428 { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
3429 NULL, 0, NULL, HFILL }},
3431 { &hf_pvfs_b_size,
3432 { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
3433 BASE_DEC, NULL, 0, "Size of bstream", HFILL }},
3435 { &hf_pvfs_k_size,
3436 { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
3437 BASE_DEC, NULL, 0, "Number of keyvals", HFILL }},
3439 { &hf_pvfs_id_gen_t,
3440 { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
3441 NULL, 0, NULL, HFILL }},
3443 { &hf_pvfs_attribute_key,
3444 { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_NONE,
3445 NULL, 0, NULL, HFILL }},
3447 { &hf_pvfs_attribute_value,
3448 { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_NONE,
3449 NULL, 0, NULL, HFILL }},
3451 { &hf_pvfs_strip_size,
3452 { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
3453 NULL, 0, "Strip size (bytes)", HFILL }},
3455 /* TODO: need description */
3456 { &hf_pvfs_ereg,
3457 { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
3458 NULL, 0, NULL, HFILL }},
3460 /* TODO: need description */
3461 { &hf_pvfs_sreg,
3462 { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
3463 NULL, 0, NULL, HFILL }},
3465 { &hf_pvfs_num_eregs,
3466 { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
3467 NULL, 0, NULL, HFILL }},
3469 { &hf_pvfs_num_blocks,
3470 { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
3471 NULL, 0, NULL, HFILL }},
3473 { &hf_pvfs_num_contig_chunks,
3474 { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
3475 BASE_DEC, NULL, 0, NULL, HFILL }},
3477 { &hf_pvfs_server_nr,
3478 { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
3479 NULL, 0, NULL, HFILL }},
3481 { &hf_pvfs_server_count,
3482 { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
3483 NULL, 0, NULL, HFILL }},
3485 { &hf_pvfs_fh_length,
3486 { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
3487 NULL, 0, "file handle length", HFILL }},
3489 { &hf_pvfs_fh_hash,
3490 { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
3491 NULL, 0, "file handle hash", HFILL }},
3493 { &hf_pvfs_permissions,
3494 { "Permissions", "pvfs.permissions", FT_UINT32, BASE_OCT,
3495 NULL, 0, NULL, HFILL }},
3497 { &hf_pvfs_server_mode,
3498 { "Server Mode", "pvfs.server_mode", FT_UINT32, BASE_DEC,
3499 VALS(names_pvfs_server_mode), 0, NULL, HFILL }},
3501 { &hf_pvfs_depth,
3502 { "depth", "pvfs.depth", FT_UINT32, BASE_DEC,
3503 NULL, 0, NULL, HFILL }},
3505 { &hf_pvfs_num_nested_req,
3506 { "num_nested_req", "pvfs.num_nested_req", FT_UINT32, BASE_DEC,
3507 NULL, 0, NULL, HFILL }},
3509 { &hf_pvfs_committed,
3510 { "committed", "pvfs.committed", FT_UINT32, BASE_DEC,
3511 NULL, 0, NULL, HFILL }},
3513 { &hf_pvfs_refcount,
3514 { "refcount", "pvfs.refcount", FT_UINT32, BASE_DEC,
3515 NULL, 0, NULL, HFILL }},
3517 { &hf_pvfs_numreq,
3518 { "numreq", "pvfs.numreq", FT_UINT32, BASE_DEC,
3519 NULL, 0, NULL, HFILL }},
3521 { &hf_pvfs_truncate_request_flags,
3522 { "flags", "pvfs.truncate_request_flags", FT_UINT32, BASE_DEC,
3523 NULL, 0, NULL, HFILL }},
3525 { &hf_pvfs_ds_position,
3526 { "ds_position", "pvfs.ds_position", FT_UINT32, BASE_DEC,
3527 NULL, 0, NULL, HFILL }},
3529 { &hf_pvfs_dirent_limit,
3530 { "dirent_limit", "pvfs.dirent_limit", FT_UINT32, BASE_DEC,
3531 NULL, 0, NULL, HFILL }},
3533 { &hf_pvfs_flush_request_flags,
3534 { "flags", "pvfs.flush_request_flags", FT_UINT32, BASE_DEC,
3535 NULL, 0, NULL, HFILL }},
3537 { &hf_pvfs_next_id,
3538 { "next_id", "pvfs.next_id", FT_UINT32, BASE_DEC,
3539 NULL, 0, NULL, HFILL }},
3541 { &hf_pvfs_mgmt_perf_mon_request_count,
3542 { "count", "pvfs.mgmt_perf_mon_request.count", FT_UINT32, BASE_DEC,
3543 NULL, 0, NULL, HFILL }},
3545 { &hf_pvfs_mgmt_perf_mon_request_event_count,
3546 { "Event count", "pvfs.mgmt_perf_mon_request.event_count", FT_UINT32, BASE_DEC,
3547 NULL, 0, NULL, HFILL }},
3549 { &hf_pvfs_lookup_path_response_handle_count,
3550 { "Handle Count", "pvfs.lookup_path_response.handle_count", FT_UINT32, BASE_DEC,
3551 NULL, 0, NULL, HFILL }},
3553 { &hf_pvfs_getconfig_response_total_bytes,
3554 { "Total Bytes", "pvfs.getconfig_response.total_bytes", FT_UINT32, BASE_DEC,
3555 NULL, 0, NULL, HFILL }},
3557 { &hf_pvfs_getconfig_response_lines,
3558 { "Lines", "pvfs.getconfig_response.lines", FT_UINT32, BASE_DEC,
3559 NULL, 0, NULL, HFILL }},
3561 { &hf_pvfs_getconfig_response_config_bytes,
3562 { "Config Bytes", "pvfs.getconfig_response.config_bytes", FT_UINT32, BASE_DEC,
3563 NULL, 0, NULL, HFILL }},
3565 { &hf_pvfs_mgmt_perf_stat_valid_flag,
3566 { "valid_flag", "pvfs.mgmt_perf_stat.valid_flag", FT_UINT32, BASE_DEC,
3567 NULL, 0, NULL, HFILL }},
3569 { &hf_pvfs_mgmt_perf_stat_id,
3570 { "id", "pvfs.mgmt_perf_stat.id", FT_UINT32, BASE_DEC,
3571 NULL, 0, NULL, HFILL }},
3573 { &hf_pvfs_mgmt_perf_mon_response_suggested_next_id,
3574 { "suggested_next_id", "pvfs.mgmt_perf_mon_response.suggested_next_id", FT_UINT32, BASE_DEC,
3575 NULL, 0, NULL, HFILL }},
3577 { &hf_pvfs_mgmt_perf_mon_response_perf_array_count,
3578 { "perf_array_count", "pvfs.mgmt_perf_mon_response.perf_array_count", FT_UINT32, BASE_DEC,
3579 NULL, 0, NULL, HFILL }},
3581 { &hf_pvfs_mgmt_iterate_handles_response_ds_position,
3582 { "ds_position", "pvfs.mgmt_iterate_handles_response.ds_position", FT_UINT32, BASE_DEC,
3583 NULL, 0, NULL, HFILL }},
3585 { &hf_pvfs_mgmt_iterate_handles_response_handle_count,
3586 { "handle_count", "pvfs.mgmt_iterate_handles_response.handle_count", FT_UINT32, BASE_DEC,
3587 NULL, 0, NULL, HFILL }},
3589 { &hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count,
3590 { "dspace_info_count", "pvfs.mgmt_dspace_info_list_response.dspace_info_count", FT_UINT32, BASE_DEC,
3591 NULL, 0, NULL, HFILL }},
3593 { &hf_pvfs_mgmt_event_mon_response_api,
3594 { "api", "pvfs.mgmt_event_mon_response.api", FT_UINT32, BASE_DEC,
3595 NULL, 0, NULL, HFILL }},
3597 { &hf_pvfs_mgmt_event_mon_response_operation,
3598 { "operation", "pvfs.mgmt_event_mon_response.operation", FT_UINT32, BASE_DEC,
3599 NULL, 0, NULL, HFILL }},
3601 { &hf_pvfs_mgmt_event_mon_response_value,
3602 { "value", "pvfs.mgmt_event_mon_response.value", FT_UINT32, BASE_DEC,
3603 NULL, 0, NULL, HFILL }},
3605 { &hf_pvfs_mgmt_event_mon_response_flags,
3606 { "flags", "pvfs.mgmt_event_mon_response.flags", FT_UINT32, BASE_DEC,
3607 NULL, 0, NULL, HFILL }},
3609 { &hf_pvfs_mgmt_event_mon_response_tv_sec,
3610 { "tv_sec", "pvfs.mgmt_event_mon_response.tv_sec", FT_UINT32, BASE_DEC,
3611 NULL, 0, NULL, HFILL }},
3613 { &hf_pvfs_mgmt_event_mon_response_tv_usec,
3614 { "tv_usec", "pvfs.mgmt_event_mon_response.tv_usec", FT_UINT32, BASE_DEC,
3615 NULL, 0, NULL, HFILL }},
3618 /* Setup protocol subtree array */
3619 static gint *ett[] = {
3620 &ett_pvfs,
3621 &ett_pvfs_hdr,
3622 &ett_pvfs_credentials,
3623 &ett_pvfs_server_config,
3624 &ett_pvfs_server_config_branch,
3625 &ett_pvfs_attrmask,
3626 &ett_pvfs_time,
3627 &ett_pvfs_extent_array_tree,
3628 &ett_pvfs_extent_item,
3629 &ett_pvfs_string,
3630 &ett_pvfs_attr_tree,
3631 &ett_pvfs_distribution,
3632 &ett_pvfs_mgmt_perf_stat,
3633 &ett_pvfs_mgmt_dspace_info,
3634 &ett_pvfs_attr,
3635 &ett_pvfs_fh
3637 module_t *pvfs_module;
3639 /* Register the protocol name and description */
3640 proto_pvfs = proto_register_protocol("Parallel Virtual File System",
3641 "PVFS", "pvfs");
3644 * Required function calls to register the header fields and
3645 * subtrees used
3648 proto_register_field_array(proto_pvfs, hf, array_length(hf));
3649 proto_register_subtree_array(ett, array_length(ett));
3651 register_init_routine(pvfs2_io_tracking_init);
3653 pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
3654 prefs_register_bool_preference(pvfs_module, "desegment",
3655 "Reassemble PVFS messages spanning multiple TCP segments",
3656 "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
3657 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3658 &pvfs_desegment);
3661 void
3662 proto_reg_handoff_pvfs(void)
3664 dissector_handle_t pvfs_handle;
3666 pvfs_handle = new_create_dissector_handle(dissect_pvfs_heur, proto_pvfs);
3667 dissector_add_uint("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
3669 heur_dissector_add("tcp", dissect_pvfs_heur, proto_pvfs);