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.
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-smb.c and others
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45 #include <epan/packet.h>
46 #include <epan/prefs.h>
47 #include <epan/emem.h>
48 #include <epan/strutil.h>
49 #include <epan/prefs.h>
50 #include "packet-tcp.h"
52 #define TCP_PORT_PVFS2 3334
54 #define PVFS2_FH_LENGTH 8
56 /* Header incl. magic number, mode, tag, size */
57 #define BMI_HEADER_SIZE 24
59 /* desegmentation of PVFS over TCP */
60 static gboolean pvfs_desegment = TRUE;
62 /* Forward declaration we need below */
63 void proto_reg_handoff_pvfs(void);
65 /* Initialize the protocol and registered fields */
66 static int proto_pvfs = -1;
67 static int hf_pvfs_magic_nr = -1;
68 static int hf_pvfs_mode = -1;
69 static int hf_pvfs_tag = -1;
70 static int hf_pvfs_size = -1;
71 static int hf_pvfs_release_number = -1;
72 static int hf_pvfs_encoding = -1;
73 static int hf_pvfs_server_op = -1;
74 static int hf_pvfs_handle = -1;
75 static int hf_pvfs_fs_id = -1;
76 static int hf_pvfs_attrmask = -1;
77 static int hf_pvfs_attr = -1;
78 static int hf_pvfs_ds_type = -1;
79 static int hf_pvfs_error = -1;
80 static int hf_pvfs_atime = -1;
81 static int hf_pvfs_atime_sec = -1;
82 static int hf_pvfs_atime_nsec = -1;
83 static int hf_pvfs_mtime = -1;
84 static int hf_pvfs_mtime_sec = -1;
85 static int hf_pvfs_mtime_nsec = -1;
86 static int hf_pvfs_ctime = -1;
87 static int hf_pvfs_ctime_sec = -1;
88 static int hf_pvfs_ctime_nsec = -1;
89 static int hf_pvfs_parent_atime = -1;
90 static int hf_pvfs_parent_atime_sec = -1;
91 static int hf_pvfs_parent_atime_nsec = -1;
92 static int hf_pvfs_parent_mtime = -1;
93 static int hf_pvfs_parent_mtime_sec = -1;
94 static int hf_pvfs_parent_mtime_nsec = -1;
95 static int hf_pvfs_parent_ctime = -1;
96 static int hf_pvfs_parent_ctime_sec = -1;
97 static int hf_pvfs_parent_ctime_nsec = -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;
148 /* Initialize the subtree pointers */
149 static gint ett_pvfs = -1;
150 static gint ett_pvfs_hdr = -1;
151 static gint ett_pvfs_credentials = -1;
152 static gint ett_pvfs_server_config = -1;
153 static gint ett_pvfs_server_config_branch = -1;
154 static gint ett_pvfs_attrmask = -1;
155 static gint ett_pvfs_time = -1;
156 static gint ett_pvfs_extent_array_tree = -1;
157 static gint ett_pvfs_extent_item = -1;
158 static gint ett_pvfs_string = -1;
159 static gint ett_pvfs_attr_tree = -1;
160 static gint ett_pvfs_distribution = -1;
161 static gint ett_pvfs_mgmt_perf_stat = -1;
162 static gint ett_pvfs_mgmt_dspace_info = -1;
163 static gint ett_pvfs_attr = -1;
164 static gint ett_pvfs_fh = -1;
166 #define BMI_MAGIC_NR 51903
168 static const value_string names_pvfs_mode[] =
170 #define TCP_MODE_IMMED 1
171 { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
172 #define TCP_MODE_UNEXP 2
173 { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
174 #define TCP_MODE_EAGER 4
175 { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
176 #define TCP_MODE_REND 8
177 { TCP_MODE_REND, "TCP_MODE_REND" },
181 static const value_string names_pvfs_encoding[] =
183 #define PVFS_ENCODING_DIRECT 1
184 { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
185 #define PVFS_ENCODING_LE_BFIELD 2
186 { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
187 #define PVFS_ENCODING_XDR 3
188 { PVFS_ENCODING_XDR, "ENCODING_XDR" },
192 static const value_string names_pvfs_io_type[] =
194 #define PVFS_IO_READ 1
195 { PVFS_IO_READ, "PVFS_IO_READ" },
196 #define PVFS_IO_WRITE 2
197 { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
201 static const value_string names_pvfs_flowproto_type[] =
203 #define FLOWPROTO_DUMP_OFFSETS 1
204 { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
205 #define FLOWPROTO_BMI_CACHE 2
206 { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
207 #define FLOWPROTO_MULTIQUEUE 3
208 { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
212 static const value_string names_pvfs_server_param[] =
214 #define PVFS_SERV_PARAM_INVALID 0
215 { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
216 #define PVFS_SERV_PARAM_GOSSIP_MASK 1
217 { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
218 #define PVFS_SERV_PARAM_FSID_CHECK 2
219 { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
220 #define PVFS_SERV_PARAM_ROOT_CHECK 3
221 { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
222 #define PVFS_SERV_PARAM_MODE 4
223 { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
224 #define PVFS_SERV_PARAM_EVENT_ON 5
225 { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
226 #define PVFS_SERV_PARAM_EVENT_MASKS 6
227 { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
231 static const value_string names_pvfs_server_mode[] =
233 #define PVFS_SERVER_NORMAL_MODE 1
234 { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
235 #define PVFS_SERVER_ADMIN_MODE 2
236 { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
240 /* Forward declaration */
242 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
243 gboolean dissect_other_as_continuation);
246 static void dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
248 dissect_pvfs_common(tvb, pinfo, tree, FALSE);
252 static guint get_pvfs_pdu_len(tvbuff_t *tvb, int offset)
257 * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
259 plen = tvb_get_letohl(tvb, offset + 16);
265 dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
267 guint32 magic_nr, mode;
270 /* verify that this is indeed PVFS and that it looks sane */
271 if(tvb_length_remaining(tvb,0)<24){
272 /* too few bytes remaining to verify the header */
276 /* validate the magic number */
277 magic_nr = tvb_get_letohl(tvb, 0);
278 if(magic_nr!=BMI_MAGIC_NR){
282 /* Validate the TCP message mode (32-bit) */
283 mode = tvb_get_letohl(tvb, 4);
291 /* invalid mode, not a PVFS packet */
295 /* validate the size : assume size must be >0 and less than 1000000 */
296 size=tvb_get_letohl(tvb, 20);
298 size|=tvb_get_letohl(tvb, 16);
299 if((size>1000000)||(size==0)){
303 tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
306 return tvb_length(tvb);
309 static const value_string names_pvfs_server_op[] =
311 #define PVFS_SERV_INVALID 0
312 { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
313 #define PVFS_SERV_CREATE 1
314 { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
315 #define PVFS_SERV_REMOVE 2
316 { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
317 #define PVFS_SERV_IO 3
318 { PVFS_SERV_IO, "PVFS_SERV_IO" },
319 #define PVFS_SERV_GETATTR 4
320 { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
321 #define PVFS_SERV_SETATTR 5
322 { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
323 #define PVFS_SERV_LOOKUP_PATH 6
324 { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
325 #define PVFS_SERV_CRDIRENT 7
326 { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
327 #define PVFS_SERV_RMDIRENT 8
328 { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
329 #define PVFS_SERV_CHDIRENT 9
330 { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
331 #define PVFS_SERV_TRUNCATE 10
332 { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
333 #define PVFS_SERV_MKDIR 11
334 { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
335 #define PVFS_SERV_READDIR 12
336 { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
337 #define PVFS_SERV_GETCONFIG 13
338 { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
339 #define PVFS_SERV_WRITE_COMPLETION 14
340 { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
341 #define PVFS_SERV_FLUSH 15
342 { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
343 #define PVFS_SERV_MGMT_SETPARAM 16
344 { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
345 #define PVFS_SERV_MGMT_NOOP 17
346 { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
347 #define PVFS_SERV_STATFS 18
348 { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
349 #define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
350 { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
351 #define PVFS_SERV_MGMT_PERF_MON 20
352 { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
353 #define PVFS_SERV_MGMT_ITERATE_HANDLES 21
354 { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
355 #define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
356 { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
357 #define PVFS_SERV_MGMT_EVENT_MON 23
358 { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
359 #define PVFS_SERV_MGMT_REMOVE_OBJECT 24
360 { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
361 #define PVFS_SERV_MGMT_REMOVE_DIRENT 25
362 { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
363 #define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
364 { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
365 #define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
366 { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
367 #define PVFS_SERV_PROTO_ERROR 28
368 { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
369 #define PVFS_SERV_GETEATTR 29
370 { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
371 #define PVFS_SERV_SETEATTR 30
372 { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
373 #define PVFS_SERV_DELEATTR 31
374 { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
378 /* special bits used to differentiate PVFS error codes from system
381 #define PVFS_ERROR_BIT (1 << 30)
383 /* a shorthand to make the error code definitions more readable */
384 #define E(num) (num|PVFS_ERROR_BIT)
386 static const value_string names_pvfs_error[] = {
388 #define PVFS_EPERM E(1) /* Operation not permitted */
389 { PVFS_EPERM, "PVFS_EPERM" },
390 #define PVFS_ENOENT E(2) /* No such file or directory */
391 { PVFS_ENOENT, "PVFS_ENOENT" },
392 #define PVFS_EINTR E(3) /* Interrupted system call */
393 { PVFS_EINTR, "PVFS_EINTR" },
394 #define PVFS_EIO E(4) /* I/O error */
395 { PVFS_EIO, "PVFS_EIO" },
396 #define PVFS_ENXIO E(5) /* No such device or address */
397 { PVFS_ENXIO, "PVFS_ENXIO" },
398 #define PVFS_EBADF E(6) /* Bad file number */
399 { PVFS_EBADF, "PVFS_EBADF" },
400 #define PVFS_EAGAIN E(7) /* Try again */
401 { PVFS_EAGAIN, "PVFS_EAGAIN" },
402 #define PVFS_ENOMEM E(8) /* Out of memory */
403 { PVFS_ENOMEM, "PVFS_ENOMEM" },
404 #define PVFS_EFAULT E(9) /* Bad address */
405 { PVFS_EFAULT, "PVFS_EFAULT" },
406 #define PVFS_EBUSY E(10) /* Device or resource busy */
407 { PVFS_EBUSY, "PVFS_EBUSY" },
408 #define PVFS_EEXIST E(11) /* File exists */
409 { PVFS_EEXIST, "PVFS_EEXIST" },
410 #define PVFS_ENODEV E(12) /* No such device */
411 { PVFS_ENODEV, "PVFS_ENODEV" },
412 #define PVFS_ENOTDIR E(13) /* Not a directory */
413 { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
414 #define PVFS_EISDIR E(14) /* Is a directory */
415 { PVFS_EISDIR, "PVFS_EISDIR" },
416 #define PVFS_EINVAL E(15) /* Invalid argument */
417 { PVFS_EINVAL, "PVFS_EINVAL" },
418 #define PVFS_EMFILE E(16) /* Too many open files */
419 { PVFS_EMFILE, "PVFS_EMFILE" },
420 #define PVFS_EFBIG E(17) /* File too large */
421 { PVFS_EFBIG, "PVFS_EFBIG" },
422 #define PVFS_ENOSPC E(18) /* No space left on device */
423 { PVFS_ENOSPC, "PVFS_ENOSPC" },
424 #define PVFS_EROFS E(19) /* Read-only file system */
425 { PVFS_EROFS, "PVFS_EROFS" },
426 #define PVFS_EMLINK E(20) /* Too many links */
427 { PVFS_EMLINK, "PVFS_EMLINK" },
428 #define PVFS_EPIPE E(21) /* Broken pipe */
429 { PVFS_EPIPE, "PVFS_EPIPE" },
430 #define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
431 { PVFS_EDEADLK, "PVFS_EDEADLK" },
432 #define PVFS_ENAMETOOLONG E(23) /* File name too long */
433 { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
434 #define PVFS_ENOLCK E(24) /* No record locks available */
435 { PVFS_ENOLCK, "PVFS_ENOLCK" },
436 #define PVFS_ENOSYS E(25) /* Function not implemented */
437 { PVFS_ENOSYS, "PVFS_ENOSYS" },
438 #define PVFS_ENOTEMPTY E(26) /* Directory not empty */
439 { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
440 #define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
441 { PVFS_ELOOP, "PVFS_ELOOP" },
442 #define PVFS_EWOULDBLOCK E(28) /* Operation would block */
443 { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
444 #define PVFS_ENOMSG E(29) /* No message of desired type */
445 { PVFS_ENOMSG, "PVFS_ENOMSG" },
446 #define PVFS_EUNATCH E(30) /* Protocol driver not attached */
447 { PVFS_EUNATCH, "PVFS_EUNATCH" },
448 #define PVFS_EBADR E(31) /* Invalid request descriptor */
449 { PVFS_EBADR, "PVFS_EBADR" },
450 #define PVFS_EDEADLOCK E(32)
451 { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
452 #define PVFS_ENODATA E(33) /* No data available */
453 { PVFS_ENODATA, "PVFS_ENODATA" },
454 #define PVFS_ETIME E(34) /* Timer expired */
455 { PVFS_ETIME, "PVFS_ETIME" },
456 #define PVFS_ENONET E(35) /* Machine is not on the network */
457 { PVFS_ENONET, "PVFS_ENONET" },
458 #define PVFS_EREMOTE E(36) /* Object is remote */
459 { PVFS_EREMOTE, "PVFS_EREMOTE" },
460 #define PVFS_ECOMM E(37) /* Communication error on send */
461 { PVFS_ECOMM, "PVFS_ECOMM" },
462 #define PVFS_EPROTO E(38) /* Protocol error */
463 { PVFS_EPROTO, "PVFS_EPROTO" },
464 #define PVFS_EBADMSG E(39) /* Not a data message */
465 { PVFS_EBADMSG, "PVFS_EBADMSG" },
466 #define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
467 { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
468 #define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
469 { PVFS_ERESTART, "PVFS_ERESTART" },
470 #define PVFS_EMSGSIZE E(42) /* Message too long */
471 { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
472 #define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
473 { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
474 #define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
475 { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
476 #define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
477 { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
478 #define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
479 { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
480 #define PVFS_EADDRINUSE E(47) /* Address already in use */
481 { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
482 #define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
483 { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
484 #define PVFS_ENETDOWN E(49) /* Network is down */
485 { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
486 #define PVFS_ENETUNREACH E(50) /* Network is unreachable */
487 { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
488 #define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
489 { PVFS_ENETRESET, "PVFS_ENETRESET" },
490 #define PVFS_ENOBUFS E(52) /* No buffer space available */
491 { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
492 #define PVFS_ETIMEDOUT E(53) /* Connection timed out */
493 { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
494 #define PVFS_ECONNREFUSED E(54) /* Connection refused */
495 { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
496 #define PVFS_EHOSTDOWN E(55) /* Host is down */
497 { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
498 #define PVFS_EHOSTUNREACH E(56) /* No route to host */
499 { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
500 #define PVFS_EALREADY E(57) /* Operation already in progress */
501 { PVFS_EALREADY, "PVFS_EALREADY" },
502 #define PVFS_EACCES E(58) /* Operation already in progress */
503 { PVFS_EACCES, "PVFS_EACCES" },
508 dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
512 const char *errmsg = NULL;
514 err = tvb_get_letohl(tvb, offset);
515 proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
518 if ((err != 0) && check_col(pinfo->cinfo, COL_INFO))
520 errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
521 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
528 dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
531 proto_item *item = NULL;
532 proto_tree *hcred_tree = NULL;
533 guint32 uid = 0, gid = 0;
535 uid = tvb_get_letohl(tvb, offset);
536 gid = tvb_get_letohl(tvb, offset + 4);
540 item = proto_tree_add_text(parent_tree, tvb, offset, 8,
541 "Credentials (UID: %d, GID: %d)", uid, gid);
544 hcred_tree = proto_item_add_subtree(item, ett_pvfs_credentials);
548 proto_tree_add_text(hcred_tree, tvb, offset, 4, "UID: %d", uid);
552 proto_tree_add_text(hcred_tree, tvb, offset, 4, "GID: %d", gid);
558 static const value_string names_pvfs_attr[] =
560 #define PVFS_ATTR_COMMON_UID (1 << 0)
561 #define PVFS_ATTR_BIT_COMMON_UID 0
562 { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
564 #define PVFS_ATTR_COMMON_GID (1 << 1)
565 #define PVFS_ATTR_BIT_COMMON_GID 1
566 { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
568 #define PVFS_ATTR_COMMON_PERM (1 << 2)
569 #define PVFS_ATTR_BIT_COMMON_PERM 2
570 { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
572 #define PVFS_ATTR_COMMON_ATIME (1 << 3)
573 #define PVFS_ATTR_BIT_COMMON_ATIME 3
574 { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
576 #define PVFS_ATTR_COMMON_CTIME (1 << 4)
577 #define PVFS_ATTR_BIT_COMMON_CTIME 4
578 { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
580 #define PVFS_ATTR_COMMON_MTIME (1 << 5)
581 #define PVFS_ATTR_BIT_COMMON_MTIME 5
582 { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
584 #define PVFS_ATTR_COMMON_TYPE (1 << 6)
585 #define PVFS_ATTR_BIT_COMMON_TYPE 6
586 { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
589 #define PVFS_ATTR_COMMON_ALL \
590 (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
591 PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
592 PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
593 PVFS_ATTR_COMMON_TYPE)
596 /* internal attribute masks for metadata objects */
597 #define PVFS_ATTR_META_DIST (1 << 10)
598 #define PVFS_ATTR_BIT_META_DIST 10
599 { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
601 #define PVFS_ATTR_META_DFILES (1 << 11)
602 #define PVFS_ATTR_BIT_META_DFILES 11
603 { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
606 #define PVFS_ATTR_META_ALL \
607 (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
610 /* internal attribute masks for datafile objects */
611 #define PVFS_ATTR_DATA_SIZE (1 << 15)
612 #define PVFS_ATTR_BIT_DATA_SIZE 15
613 { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
616 #define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
619 /* internal attribute masks for symlink objects */
620 #define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
621 #define PVFS_ATTR_BIT_SYMLINK_TARGET 18
622 { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
625 #define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
628 /* internal attribute masks for directory objects */
629 #define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
630 #define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
631 { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
634 #define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
637 /* attribute masks used by system interface callers */
638 #define PVFS_ATTR_SYS_SIZE (1 << 20)
639 #define PVFS_ATTR_BIT_SYS_SIZE 20
640 { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
642 #define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
643 #define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
644 { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
646 #define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
647 #define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
648 { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
650 #define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
651 #define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
652 { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
655 #define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
656 #define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
657 #define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
658 #define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
659 #define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
660 #define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
661 #define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
667 #define PVFS_ATTR_SYS_ALL \
668 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
669 PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
670 PVFS_ATTR_SYS_DIRENT_COUNT)
672 #define PVFS_ATTR_SYS_ALL_NOSIZE \
673 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
674 PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
676 #define PVFS_ATTR_SYS_ALL_SETABLE \
677 (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
682 dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
685 guint32 attrmask = 0, i = 0;
686 proto_item *attritem = NULL;
687 proto_tree *attrtree = NULL;
689 attrmask = tvb_get_letohl(tvb, offset);
691 attritem = proto_tree_add_text(tree, tvb, offset, 4,
692 "Attribute Mask: %d", attrmask);
695 attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
697 for (i = 0; i < 32; i++)
699 if (attrmask & (1 << i))
700 proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
706 *pattrmask = attrmask;
711 static const value_string names_pvfs_ds_type[] = {
712 #define PVFS_TYPE_NONE 0
713 { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
714 #define PVFS_TYPE_METAFILE (1 << 0)
715 { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
716 #define PVFS_TYPE_DATAFILE (1 << 1)
717 { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
718 #define PVFS_TYPE_DIRECTORY (1 << 2)
719 { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
720 #define PVFS_TYPE_SYMLINK (1 << 3)
721 { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
722 #define PVFS_TYPE_DIRDATA (1 << 4)
723 { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
728 dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
733 ds_type = tvb_get_letohl(tvb, offset);
736 proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
746 #define roundup4(x) (((x) + 3) & ~3)
747 #define roundup8(x) (((x) + 7) & ~7)
750 dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
752 packet_info *pinfo _U_,
754 gboolean fixed_length, guint32 length,
755 gboolean string_data, char **string_buffer_ret)
758 proto_item *string_item = NULL;
759 proto_tree *string_tree = NULL;
761 guint32 string_length;
762 guint32 string_length_full;
763 guint32 string_length_packet;
764 guint32 string_length_captured;
765 guint32 string_length_copy;
769 guint32 fill_length_packet;
770 guint32 fill_length_captured;
771 guint32 fill_length_copy;
775 char *string_buffer = NULL;
776 char *string_buffer_print = NULL;
779 string_length = length;
780 data_offset = offset;
782 string_length = tvb_get_letohl(tvb,offset+0);
783 data_offset = offset + 4;
786 * Variable-length strings include NULL terminator on-the-wire but
787 * NULL terminator is not included in string length.
794 string_length_captured = tvb_length_remaining(tvb, data_offset);
795 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
798 * Strangeness... the protocol basically says that the length plus
799 * the string must be padded out to an 8-byte boundary.
803 string_length_full = roundup4(string_length);
805 string_length_full = roundup8(4 + string_length);
807 if (string_length_captured < string_length) {
808 /* truncated string */
809 string_length_copy = string_length_captured;
812 fill_length_copy = 0;
814 if (string_length_packet < string_length)
815 exception = ReportedBoundsError;
817 exception = BoundsError;
820 /* full string data */
821 string_length_copy = string_length;
824 fill_length = string_length_full - string_length;
826 fill_length = string_length_full - string_length - 4;
828 fill_length_captured = tvb_length_remaining(tvb,
829 data_offset + string_length);
830 fill_length_packet = tvb_reported_length_remaining(tvb,
831 data_offset + string_length);
833 if (fill_length_captured < fill_length) {
834 /* truncated fill bytes */
835 fill_length_copy = fill_length_packet;
837 if (fill_length_packet < fill_length)
838 exception = ReportedBoundsError;
840 exception = BoundsError;
843 /* full fill bytes */
844 fill_length_copy = fill_length;
852 tmpstr = (char *) tvb_get_ephemeral_string(tvb, data_offset,
855 string_buffer = memcpy(ep_alloc(string_length_copy+1), tmpstr, string_length_copy);
857 string_buffer = (char *) tvb_memcpy(tvb,
858 ep_alloc(string_length_copy+1), data_offset, string_length_copy);
861 string_buffer[string_length_copy] = '\0';
863 /* calculate a nice printable string */
865 if (string_length != string_length_copy) {
868 guint16 string_buffer_size = 0;
870 formatted = format_text((guint8 *)string_buffer,
871 strlen(string_buffer));
873 string_buffer_size = strlen(formatted) + 12 + 1;
875 /* alloc maximum data area */
876 string_buffer_print = (char*) ep_alloc(string_buffer_size);
877 /* copy over the data */
878 g_snprintf(string_buffer_print, string_buffer_size - 1,
879 "%s<TRUNCATED>", formatted);
880 /* append <TRUNCATED> */
881 /* This way, we get the TRUNCATED even
882 in the case of totally wrong packets,
883 where \0 are inside the string.
884 TRUNCATED will appear at the
885 first \0 or at the end (where we
886 put the securing \0).
889 string_buffer_print="<DATA><TRUNCATED>";
893 string_buffer_print = (char *)
894 ep_strdup(format_text((guint8 *) string_buffer,
895 strlen(string_buffer)));
897 string_buffer_print="<DATA>";
901 string_buffer_print="<EMPTY>";
905 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
906 "%s: %s", proto_registrar_get_name(hfindex),
907 string_buffer_print);
910 string_tree = proto_item_add_subtree(string_item,
915 proto_tree_add_text(string_tree, tvb,offset+0,4,
916 "length: %u (excl. NULL terminator)", string_length - 1);
922 proto_tree_add_string_format(string_tree,
923 hfindex, tvb, offset, string_length_copy,
925 "contents: %s", string_buffer_print);
927 proto_tree_add_bytes_format(string_tree,
928 hfindex, tvb, offset, string_length_copy,
929 (guint8 *) string_buffer,
930 "contents: %s", string_buffer_print);
934 offset += string_length_copy;
938 if (fill_truncated) {
939 proto_tree_add_text(string_tree, tvb,
940 offset,fill_length_copy,
941 "fill bytes: opaque data<TRUNCATED>");
944 proto_tree_add_text(string_tree, tvb,
945 offset,fill_length_copy,
946 "fill bytes: opaque data");
949 offset += fill_length_copy;
953 proto_item_set_end(string_item, tvb, offset);
955 if (string_buffer_ret != NULL)
956 *string_buffer_ret = string_buffer_print;
959 * If the data was truncated, throw the appropriate exception,
960 * so that dissection stops and the frame is properly marked.
969 dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
970 int offset, char **string_buffer_ret)
972 return dissect_pvfs_opaque_data(tvb, offset, tree, NULL, hfindex,
973 FALSE, 0, TRUE, string_buffer_ret);
977 dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
983 bytes_left = PVFS2_FH_LENGTH;
985 while (bytes_left != 0) {
987 if (sublen > bytes_left)
989 proto_tree_add_text(tree, tvb, offset, sublen,
991 first_line ? "data: " :
993 tvb_bytes_to_str(tvb,offset,sublen));
994 bytes_left -= sublen;
1001 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1002 proto_tree *tree, guint32 *hash)
1007 /* Not all bytes there. Any attempt to deduce the type would be
1009 if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
1012 /* create a semiunique hash value for the filehandle */
1013 for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
1015 val = tvb_get_ntohl(tvb, offset+i);
1020 proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
1026 /* TODO: add file name snooping code here */
1029 dissect_fhandle_data_unknown(tvb, offset, tree);
1033 dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
1034 proto_tree *tree, const char *name, guint32 *hash)
1036 proto_item* fitem = NULL;
1037 proto_tree* ftree = NULL;
1041 fitem = proto_tree_add_text(tree, tvb, offset, PVFS2_FH_LENGTH,
1045 ftree = proto_item_add_subtree(fitem, ett_pvfs_fh);
1048 /* TODO: add fh to file name snooping code here */
1050 proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
1053 dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
1055 offset += PVFS2_FH_LENGTH;
1061 dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
1062 packet_info *pinfo, guint32 nCount)
1064 proto_item *extent_item = NULL;
1065 proto_tree *extent_tree = NULL;
1069 extent_item = proto_tree_add_text(tree, tvb, offset, 8,
1073 extent_tree = proto_item_add_subtree(extent_item,
1074 ett_pvfs_extent_item);
1078 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
1082 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
1089 dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
1092 guint32 extent_count = 0;
1094 proto_item *extent_array_item = NULL;
1095 proto_tree *extent_array_tree = NULL;
1098 extent_count = tvb_get_letohl(tvb, offset);
1101 extent_array_item = proto_tree_add_text(tree, tvb, offset, 4,
1102 "Handle Extent Array (count = %d)", extent_count);
1106 if (extent_count > 0)
1108 if (extent_array_item)
1109 extent_array_tree = proto_item_add_subtree(extent_array_item,
1110 ett_pvfs_extent_array_tree);
1112 /* Add extent array items */
1113 for (nCount = 0; nCount < extent_count; nCount++)
1114 offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
1122 dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
1123 int hf_time, int hf_time_sec, int hf_time_nsec)
1128 proto_item *time_item = NULL;
1129 proto_tree *time_tree = NULL;
1131 ts.secs = seconds = tvb_get_letohl(tvb, offset);
1132 ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
1136 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
1139 time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
1144 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
1145 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4,
1154 int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
1155 int hfindex, guint64 *pvalue)
1159 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1160 tvb_get_letohl(tvb, offset);
1162 proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
1170 /* Taken from pvfs2-dist-simple-stripe.h */
1171 #define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
1172 #define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
1175 dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset)
1177 proto_item *dist_item = NULL;
1178 proto_tree *dist_tree = NULL;
1179 char *distname = NULL;
1180 guint32 distlen = 0;
1181 char *tmpstr = NULL;
1182 guint8 issimplestripe = 0;
1184 /* Get distribution name length */
1185 distlen = tvb_get_letohl(tvb, offset);
1187 /* Get distribution name */
1188 tmpstr = (char *) tvb_get_ephemeral_string(tvb, offset + 4, distlen);
1194 /* 'distlen' does not include the NULL terminator */
1195 total_len = roundup8(4 + distlen + 1);
1197 if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
1198 (strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
1201 /* Parameter for 'simple_stripe' is 8 bytes */
1207 dist_item = proto_tree_add_text(tree, tvb, offset, total_len + 8,
1208 "Distribution: %s", tmpstr);
1211 dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
1215 offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
1218 /* TODO: only one distribution type is currently supported */
1220 offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
1221 hf_pvfs_strip_size, NULL);
1229 dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
1232 guint32 dfile_count, i;
1235 dfile_count = tvb_get_letohl(tvb, offset);
1236 proto_tree_add_text(tree, tvb, offset, 4, "dfile_count: %d",
1240 for (i = 0; i < dfile_count; i++)
1241 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1247 dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
1251 guint32 attrmask = 0;
1252 proto_item *attr_item = NULL;
1253 proto_tree *attr_tree = NULL;
1257 attr_item = proto_tree_add_text(tree, tvb, offset, -1, "Attributes");
1260 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr_tree);
1264 proto_tree_add_text(attr_tree, tvb, offset, 4, "UID: %d",
1265 tvb_get_letohl(tvb, offset));
1269 proto_tree_add_text(attr_tree, tvb, offset, 4, "GID: %d",
1270 tvb_get_letohl(tvb, offset));
1274 proto_tree_add_text(attr_tree, tvb, offset, 4, "Permissions: %o",
1275 tvb_get_letohl(tvb, offset));
1281 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
1282 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1285 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
1286 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1289 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
1290 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1293 offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
1296 offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
1298 if (attrmask & PVFS_ATTR_META_DIST)
1300 offset = dissect_pvfs_distribution(tvb, attr_tree, offset);
1302 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1306 if (attrmask & PVFS_ATTR_META_DFILES)
1308 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1312 if (attrmask & PVFS_ATTR_DATA_SIZE)
1314 offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
1319 if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
1321 /* target_path_len */
1322 proto_tree_add_text(attr_tree, tvb, offset, 4,
1323 "target_path_len: %d", tvb_get_letohl(tvb, offset));
1329 offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
1334 if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
1336 offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
1337 hf_pvfs_size, NULL);
1348 dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1350 proto_tree_add_uint(tree, hf_pvfs_io_type, tvb, offset, 4,
1351 tvb_get_letohl(tvb, offset));
1358 dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1360 proto_tree_add_uint(tree, hf_pvfs_flowproto_type, tvb, offset, 4,
1361 tvb_get_letohl(tvb, offset));
1368 dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
1371 guint32 server_param = 0;
1375 server_param = tvb_get_letohl(tvb, offset);
1376 proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
1380 switch (server_param)
1382 case PVFS_SERV_PARAM_MODE:
1383 lowpart = tvb_get_letohl(tvb, offset);
1385 proto_tree_add_text(tree, tvb, offset, 8,
1386 "Server Mode: %s (%u)",
1387 val_to_str(lowpart, names_pvfs_server_mode, "%u"), lowpart);
1390 case PVFS_SERV_PARAM_FSID_CHECK:
1391 lowpart = tvb_get_letohl(tvb, offset);
1392 proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4, lowpart);
1393 proto_tree_add_uint(tree, hf_pvfs_unused, tvb, offset + 4, 4,
1394 tvb_get_letohl(tvb, offset + 4));
1397 case PVFS_SERV_PARAM_ROOT_CHECK:
1398 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1408 dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1411 proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4,
1412 tvb_get_letohl(tvb, offset));
1420 * =======================================================================
1422 * =======================================================================
1426 dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1430 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1433 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
1437 offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
1443 dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1447 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1450 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1456 dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
1462 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1463 tvb_get_letohl(tvb, offset);
1464 proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
1467 /* TODO: num_eregs */
1468 proto_tree_add_uint(tree, hf_pvfs_num_eregs, tvb, offset, 4,
1469 tvb_get_letohl(tvb, offset));
1472 /* TODO: num_blocks */
1473 proto_tree_add_uint(tree, hf_pvfs_num_blocks, tvb, offset, 4,
1474 tvb_get_letohl(tvb, offset));
1478 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1479 tvb_get_letohl(tvb, offset);
1480 proto_tree_add_uint64(tree, hf_pvfs_stride, tvb, offset, 8, val);
1484 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1485 tvb_get_letohl(tvb, offset);
1486 proto_tree_add_uint64(tree, hf_pvfs_ub, tvb, offset, 8, val);
1490 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1491 tvb_get_letohl(tvb, offset);
1492 proto_tree_add_uint64(tree, hf_pvfs_lb, tvb, offset, 8, val);
1495 /* TODO: aggregate size */
1496 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1497 tvb_get_letohl(tvb, offset);
1498 proto_tree_add_uint64(tree, hf_pvfs_aggregate_size, tvb, offset, 8, val);
1501 /* num_contig_chunks */
1502 proto_tree_add_uint(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4,
1503 tvb_get_letohl(tvb, offset));
1507 proto_tree_add_text(tree, tvb, offset, 4, "depth: %d",
1508 tvb_get_letohl(tvb, offset));
1511 /* num_nested_req */
1512 proto_tree_add_text(tree, tvb, offset, 4, "num_nested_req: %d",
1513 tvb_get_letohl(tvb, offset));
1517 proto_tree_add_text(tree, tvb, offset, 4, "committed: %d",
1518 tvb_get_letohl(tvb, offset));
1522 proto_tree_add_text(tree, tvb, offset, 4, "refcount: %d",
1523 tvb_get_letohl(tvb, offset));
1530 ereg = tvb_get_letohl(tvb, offset);
1531 proto_tree_add_int(tree, hf_pvfs_ereg, tvb, offset, 4, ereg);
1535 sreg = tvb_get_letohl(tvb, offset);
1536 proto_tree_add_int(tree, hf_pvfs_sreg, tvb, offset, 4, sreg);
1543 dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1549 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1552 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1554 /* skip4 as per source code */
1558 offset = dissect_pvfs_io_type(tvb, tree, offset);
1561 offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
1564 proto_tree_add_uint(tree, hf_pvfs_server_nr, tvb, offset, 4,
1565 tvb_get_letohl(tvb, offset));
1569 proto_tree_add_uint(tree, hf_pvfs_server_count, tvb, offset, 4,
1570 tvb_get_letohl(tvb, offset));
1574 offset = dissect_pvfs_distribution(tvb, tree, offset);
1576 proto_tree_add_text(tree, tvb, offset, 4, "numreq: %d",
1577 tvb_get_letohl(tvb, offset));
1583 offset = dissect_pvfs_pint_request(tvb, tree, offset);
1585 /* TODO: remove this!!! */
1586 offset = tvb_length(tvb) - 16;
1589 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1590 tvb_get_letohl(tvb, offset);
1591 proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
1595 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1596 tvb_get_letohl(tvb, offset);
1597 proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
1604 dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1608 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1611 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1614 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1620 dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1624 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1626 /* parent_ref: fs_id */
1627 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1631 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1636 /* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
1638 dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
1639 int offset, packet_info *pinfo)
1642 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1645 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1649 /* starting_handle */
1650 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1652 /* attribute mask */
1653 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1659 dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1663 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1665 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
1668 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1671 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1676 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1677 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1680 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1681 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1684 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1685 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1690 /* TODO: incomplete */
1692 dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1696 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1699 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1702 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1707 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1708 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1711 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1712 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1715 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1716 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1722 dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1726 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1728 /* New directory entry handle */
1729 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
1733 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1736 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1739 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
1740 hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
1743 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
1744 hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
1747 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
1748 hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
1754 dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1760 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1763 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1768 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1769 tvb_get_letohl(tvb, offset);
1770 proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
1774 proto_tree_add_text(tree, tvb, offset, 4, "flags: %u",
1775 tvb_get_letohl(tvb, offset));
1782 dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1788 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1793 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1795 /* handle_extent_array */
1796 count = tvb_get_letohl(tvb, offset);
1799 for (i = 0; i < count; i++)
1800 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1806 dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1809 /* object_ref: handle */
1810 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1812 /* object_ref: fs_id */
1813 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1816 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
1817 tvb_get_letohl(tvb, offset));
1821 proto_tree_add_text(tree, tvb, offset, 4, "dirent_limit: %d",
1822 tvb_get_letohl(tvb, offset));
1829 dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
1830 int offset, packet_info *pinfo)
1833 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1836 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1839 proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
1840 tvb_get_letohl(tvb, offset));
1847 dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
1848 int offset, packet_info *pinfo)
1851 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1854 offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
1860 dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1861 packet_info *pinfo _U_)
1864 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1870 dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
1871 int offset, packet_info *pinfo _U_)
1874 proto_tree_add_text(tree, tvb, offset, 4, "next_id: %d",
1875 tvb_get_letohl(tvb, offset));
1879 proto_tree_add_text(tree, tvb, offset, 4, "count: %d",
1880 tvb_get_letohl(tvb, offset));
1887 dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
1888 int offset, packet_info *pinfo)
1891 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1894 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1900 dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
1901 proto_tree *tree, int offset, packet_info *pinfo)
1903 guint32 handle_count, i;
1906 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1909 handle_count = tvb_get_letohl(tvb, offset);
1912 for (i = 0; i < handle_count; i++)
1915 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1922 dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
1923 int offset, packet_info *pinfo _U_)
1926 proto_tree_add_text(tree, tvb, offset, 4, "Event count: %d",
1927 tvb_get_letohl(tvb, offset));
1934 dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
1935 int offset, packet_info *pinfo)
1938 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1941 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1947 dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
1948 proto_tree *tree, int offset, packet_info *pinfo)
1951 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1954 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1960 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1966 dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
1967 proto_tree *tree, int offset, packet_info *pinfo)
1970 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1973 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1978 /* TODO: untested/incomplete */
1980 dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset)
1983 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
1986 /* attribute value */
1987 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
1993 /* TODO: incomplete/untested */
1995 dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset)
1999 /* number of keys and vals */
2000 nKey = tvb_get_letohl(tvb, offset);
2003 for (i = 0; i < nKey; i++)
2004 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
2009 /* TODO: incomplete/untested */
2011 dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
2012 int offset, packet_info *pinfo)
2015 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2018 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2022 offset = dissect_ds_keyval_array(tvb, tree, offset);
2027 /* TODO: incomplete/untested */
2029 dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
2030 int offset, packet_info *pinfo)
2033 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2036 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2040 offset = dissect_ds_keyval_array(tvb, tree, offset);
2045 /* TODO: untested */
2047 dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
2048 int offset, packet_info *pinfo)
2051 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2054 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2057 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
2063 dissect_pvfs2_release_number(tvbuff_t *tvb, proto_tree *tree, int offset)
2065 guint32 release_nr = tvb_get_letohl(tvb, offset);
2067 proto_tree_add_text(tree, tvb, offset, 4,
2068 "PVFS2 Release Number: %d (%d.%d.%d)",
2071 (release_nr % 10000) / 100,
2072 (release_nr % 10000) % 100);
2079 dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
2081 /* PVFS release number */
2082 offset = dissect_pvfs2_release_number(tvb, tree, offset);
2084 /* wire encoding type */
2085 proto_tree_add_uint(tree, hf_pvfs_encoding, tvb, offset,
2086 4, tvb_get_letohl(tvb, offset));
2090 proto_tree_add_uint(tree, hf_pvfs_server_op, tvb, offset, 4,
2091 tvb_get_letohl(tvb, offset));
2098 dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
2099 packet_info *pinfo, guint32 server_op)
2102 proto_tree_add_uint(tree, hf_pvfs_context_id, tvb, offset,
2103 4, tvb_get_letohl(tvb, offset));
2107 offset = dissect_pvfs_credentials(tvb, tree, offset);
2111 case PVFS_SERV_CREATE:
2112 offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
2115 case PVFS_SERV_REMOVE:
2116 offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
2120 offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
2123 case PVFS_SERV_GETATTR:
2124 offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
2127 case PVFS_SERV_SETATTR:
2128 offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
2131 case PVFS_SERV_LOOKUP_PATH:
2132 offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
2135 case PVFS_SERV_CRDIRENT:
2136 offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
2139 case PVFS_SERV_RMDIRENT:
2140 offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
2143 case PVFS_SERV_CHDIRENT:
2144 offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
2147 case PVFS_SERV_TRUNCATE:
2148 offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
2151 case PVFS_SERV_MKDIR:
2152 offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
2155 case PVFS_SERV_READDIR:
2156 offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
2160 case PVFS_SERV_GETCONFIG:
2161 /* No parameters in request */
2166 case PVFS_SERV_WRITE_COMPLETION:
2167 /* No parameters in request */
2171 case PVFS_SERV_FLUSH:
2172 offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
2175 case PVFS_SERV_MGMT_SETPARAM:
2176 offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
2181 case PVFS_SERV_MGMT_NOOP:
2182 /* No parameters in request */
2186 case PVFS_SERV_STATFS:
2187 offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
2191 case PVFS_SERV_PERF_UPDATE:
2192 /* No parameters in request */
2196 case PVFS_SERV_MGMT_PERF_MON:
2197 offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
2201 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2202 offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
2206 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2207 offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
2211 case PVFS_SERV_MGMT_EVENT_MON:
2212 offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
2216 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2217 offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
2221 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2222 offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
2226 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2227 offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
2232 case PVFS_SERV_JOB_TIMER:
2233 /* No parameters in request */
2237 case PVFS_SERV_PROTO_ERROR:
2238 /* TODO: is this necessary? */
2241 case PVFS_SERV_GETEATTR:
2242 offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
2245 case PVFS_SERV_SETEATTR:
2246 offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
2249 case PVFS_SERV_DELEATTR:
2250 offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
2254 /* TODO: what should we do here? */
2262 * =======================================================================
2264 * =======================================================================
2268 dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2272 return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2276 dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2278 return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
2282 dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
2283 int offset, packet_info *pinfo)
2285 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
2291 dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
2292 int offset, packet_info *pinfo)
2295 guint32 handle_count = 0;
2296 guint32 attr_count = 0;
2297 proto_item *attr_item = NULL;
2298 proto_tree *attr_tree = NULL;
2303 handle_count = tvb_get_letohl(tvb, offset);
2304 proto_tree_add_text(tree, tvb, offset, 4, "Handle Count: %d",
2308 /* TODO: add bounds checking */
2309 for (nCount = 0; nCount < handle_count; nCount++)
2310 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2314 /* array of attributes */
2315 attr_count = tvb_get_letohl(tvb, offset);
2319 attr_item = proto_tree_add_text(tree, tvb, offset, 4,
2320 "Attribute array (total items: %d)", attr_count);
2323 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr);
2328 /* Array of attributes */
2329 for (nCount = 0; nCount < attr_count; nCount++)
2330 offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
2336 dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2340 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2346 dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2350 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2356 dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2360 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2366 dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2370 guint32 dirent_count = 0;
2374 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
2375 tvb_get_letohl(tvb, offset));
2380 /* directory_version */
2381 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
2382 tvb_get_letohl(tvb, offset);
2383 proto_tree_add_uint64(tree, hf_pvfs_directory_version, tvb, offset, 8,
2390 dirent_count = tvb_get_letohl(tvb, offset);
2391 proto_tree_add_text(tree, tvb, offset, 4, "dirent_count: %d",
2395 for (nCount = 0; nCount < dirent_count; nCount++)
2397 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
2398 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2405 * TODO: this code needs work! Not finished yet!
2408 dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
2412 guint32 total_bytes = 0, total_config_bytes = 0, total_lines = 0;
2413 guint32 bytes_processed = 0;
2414 guint32 length_remaining = 0;
2416 proto_item *item = NULL, *config_item = NULL;
2417 proto_tree *tree = NULL, *config_tree = NULL;
2418 guint8 truncated = 0;
2422 item = proto_tree_add_text(parent_tree, tvb, offset, 12,
2426 tree = proto_item_add_subtree(item, ett_pvfs_server_config);
2429 /* Total number of bytes in server config (incl. entry count) */
2430 total_bytes = tvb_get_letohl(tvb, offset);
2431 proto_tree_add_text(tree, tvb, offset, 4, "Total Bytes: %d",
2435 /* There must be at least 4 bytes of data returned to determine the
2436 * size of the server config data
2438 if (total_bytes < 4)
2440 /* Server config not returned, bail out */
2444 /* Number of entries in server config */
2445 total_lines = tvb_get_letohl(tvb, offset);
2446 proto_tree_add_text(tree, tvb, offset, 4, "Lines: %d", total_lines);
2449 /* Number of bytes in server config */
2450 total_config_bytes = tvb_get_letohl(tvb, offset);
2451 proto_tree_add_text(tree, tvb, offset, 4, "Config Bytes: %d",
2452 total_config_bytes);
2455 /* Get pointer to server config data */
2456 ptr = (char *) tvb_get_ptr(tvb, offset, total_config_bytes);
2458 /* Check if all data is available */
2459 length_remaining = tvb_length_remaining(tvb, offset);
2461 if (length_remaining < total_config_bytes)
2463 total_config_bytes = length_remaining;
2468 bytes_processed = 0;
2470 for (i = 0; i < total_lines; i++)
2472 guint8 entry[256], *pentry = entry, *tmp_entry = NULL;
2473 guint32 entry_length = 0, tmp_entry_length = 0;
2474 guint32 bufsiz = sizeof(entry);
2476 while ((*ptr != '\n') && (*ptr != '\0') &&
2477 (bytes_processed < total_config_bytes) &&
2478 (entry_length < bufsiz))
2486 if ((entry_length == bufsiz) &&
2487 ((entry[entry_length - 1] != '\n') ||
2488 (entry[entry_length - 1] != '\0')))
2491 * Single line of config data doesn't fit into provided buffer,
2492 * config data is malformed.
2498 if (bytes_processed == total_config_bytes)
2500 /* Oops... ran out of data before we could complete the entry */
2507 tmp_entry_length = entry_length;
2509 /* Remove all whitespace from front of entry */
2510 while ((tmp_entry_length > 0) && (!isalnum(*tmp_entry)) &&
2511 (*tmp_entry != '<'))
2517 if (tmp_entry[0] == '<')
2519 if (tmp_entry[tmp_entry_length - 1] == '>')
2522 if (tmp_entry[1] != '/')
2524 /* Opening token, create new tree root */
2525 config_item = proto_tree_add_text(tree, tvb, offset,
2526 tmp_entry_length, "%s", tmp_entry);
2529 config_tree = proto_item_add_subtree(config_item,
2530 ett_pvfs_server_config_branch);
2541 /* Malformed token */
2547 /* Insert items into the root config tree if there's no subtree
2550 if (config_tree == NULL)
2553 if (tmp_entry_length > 0)
2555 proto_tree_add_text(config_tree, tvb, offset, tmp_entry_length,
2560 offset += entry_length + 1;
2566 if (bytes_processed < total_config_bytes)
2568 /* We ran out of server config data */
2569 proto_tree_add_text(config_tree, tvb, offset, -1,
2570 "<MALFORMED OR TRUNCATED DATA>");
2577 dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
2581 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
2588 dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
2594 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
2595 tvb_get_letohl(tvb, offset);
2597 proto_tree_add_uint64(tree, hf_pvfs_prev_value, tvb, offset, 8, val);
2605 dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2610 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2612 /* bytes_available */
2613 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
2617 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
2620 /* RAM bytes total */
2621 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
2624 /* RAM bytes free */
2625 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
2628 /* load average (1s) */
2629 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
2632 /* load average (5s) */
2633 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
2636 /* load average (15s) */
2637 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
2640 /* uptime (seconds) */
2641 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
2644 /* handles_available_count */
2645 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
2648 /* handles_total_count */
2649 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
2656 dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
2659 proto_item *stat_item = NULL;
2660 proto_tree *stat_tree = NULL;
2664 stat_item = proto_tree_add_text(tree, tvb, offset, 48,
2665 "Stat Array - Element %d", nItem);
2668 stat_tree = proto_item_add_subtree(stat_item,
2669 ett_pvfs_mgmt_perf_stat);
2672 /* TODO: valid_flag */
2673 proto_tree_add_text(stat_tree, tvb, offset, 4, "valid_flag: %d",
2674 tvb_get_letohl(tvb, offset));
2678 proto_tree_add_text(stat_tree, tvb, offset, 4, "id: %d",
2679 tvb_get_letohl(tvb, offset));
2682 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
2684 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
2686 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
2688 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
2690 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
2697 dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
2700 guint32 perf_array_count, i;
2702 /* TODO: suggested_next_id */
2703 proto_tree_add_text(tree, tvb, offset, 4, "suggested_next_id: %d",
2704 tvb_get_letohl(tvb, offset));
2709 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms,
2711 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms,
2716 /* TODO: perf_array_count */
2717 perf_array_count = tvb_get_letohl(tvb, offset);
2718 proto_tree_add_text(tree, tvb, offset, 4, "perf_array_count: %d",
2722 for (i = 0; i < perf_array_count; i++)
2723 offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
2729 dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
2730 int offset, packet_info *pinfo)
2732 guint32 handle_count, i;
2735 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
2736 tvb_get_letohl(tvb, offset));
2740 handle_count = tvb_get_letohl(tvb, offset);
2741 proto_tree_add_text(tree, tvb, offset, 4, "handle_count: %d",
2745 /* TODO: this could be improved */
2746 for (i = 0; i < handle_count; i++)
2747 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2753 dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
2756 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2757 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2758 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
2759 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
2761 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
2763 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2769 dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
2770 int offset, packet_info *pinfo)
2772 guint32 dspace_info_count, i;
2773 proto_item *arr_item = NULL;
2774 proto_tree *arr_tree = NULL;
2778 /* dspace_info_count */
2779 dspace_info_count = tvb_get_letohl(tvb, offset);
2780 proto_tree_add_text(tree, tvb, offset, 4, "dspace_info_count: %d",
2783 if ((dspace_info_count > 0) && (tree))
2785 arr_item = proto_tree_add_text(tree, tvb, offset,
2786 dspace_info_count * 40, "dspace_info Array (%d items)",
2790 arr_tree = proto_item_add_subtree(arr_item,
2791 ett_pvfs_mgmt_dspace_info);
2794 for (i = 0; i < dspace_info_count; i++)
2795 offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
2801 dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
2805 proto_tree_add_text(tree, tvb, offset, 4, "api: %d",
2806 tvb_get_letohl(tvb, offset));
2810 proto_tree_add_text(tree, tvb, offset, 4, "operation: %d",
2811 tvb_get_letohl(tvb, offset));
2815 proto_tree_add_text(tree, tvb, offset, 4, "value: %d",
2816 tvb_get_letohl(tvb, offset));
2820 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
2824 proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
2825 tvb_get_letohl(tvb, offset));
2829 proto_tree_add_text(tree, tvb, offset, 4, "tv_sec: %d",
2830 tvb_get_letohl(tvb, offset));
2834 proto_tree_add_text(tree, tvb, offset, 4, "tv_usec: %d",
2835 tvb_get_letohl(tvb, offset));
2844 dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
2845 int offset, packet_info *pinfo)
2848 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2851 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2857 dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
2858 proto_tree *tree, int offset, packet_info *pinfo)
2861 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2866 /* TODO: untested */
2868 dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2869 packet_info *pinfo _U_)
2873 /* Dissect nKey & ds_keyval array */
2874 offset = dissect_ds_keyval_array(tvb, tree, offset);
2880 dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2881 packet_info *pinfo, guint32 server_op)
2884 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2888 case PVFS_SERV_CREATE:
2889 offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
2893 case PVFS_SERV_REMOVE:
2894 /* No result data */
2899 offset = dissect_pvfs2_io_response(tvb, tree, offset);
2902 case PVFS_SERV_GETATTR:
2903 offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
2906 case PVFS_SERV_SETATTR:
2907 /* No result data */
2910 case PVFS_SERV_LOOKUP_PATH:
2911 offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
2915 case PVFS_SERV_CRDIRENT:
2916 /* No result data */
2920 case PVFS_SERV_RMDIRENT:
2921 offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
2924 case PVFS_SERV_CHDIRENT:
2925 offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
2929 case PVFS_SERV_TRUNCATE:
2930 /* No result data */
2934 case PVFS_SERV_MKDIR:
2935 offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
2938 case PVFS_SERV_READDIR:
2939 offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
2942 case PVFS_SERV_GETCONFIG:
2943 offset = dissect_pvfs2_getconfig_response(tvb, tree, offset);
2946 case PVFS_SERV_WRITE_COMPLETION:
2947 offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
2951 case PVFS_SERV_FLUSH:
2952 /* No result data */
2956 case PVFS_SERV_MGMT_SETPARAM:
2957 offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
2961 case PVFS_SERV_MGMT_NOOP:
2962 /* No result data */
2966 case PVFS_SERV_STATFS:
2967 offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
2971 case PVFS_SERV_PERF_UPDATE:
2972 /* No result data */
2976 case PVFS_SERV_MGMT_PERF_MON:
2977 offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
2980 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2981 offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
2985 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2986 offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
2990 case PVFS_SERV_MGMT_EVENT_MON:
2991 offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
2994 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2995 offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
3000 case PVFS_SERV_MGMT_REMOVE_DIRENT:
3001 /* No result data */
3005 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
3006 offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
3011 case PVFS_SERV_JOB_TIMER:
3012 /* No result data */
3016 case PVFS_SERV_PROTO_ERROR:
3017 /* No result data */
3020 /* TODO: untested */
3021 case PVFS_SERV_GETEATTR:
3022 offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
3026 case PVFS_SERV_SETEATTR:
3027 /* No result data */
3032 case PVFS_SERV_DELEATTR:
3033 /* No result data */
3038 /* TODO: what do we do here? */
3045 static GHashTable *pvfs2_io_tracking_value_table = NULL;
3047 typedef struct pvfs2_io_tracking_key
3050 } pvfs2_io_tracking_key_t;
3052 typedef struct pvfs2_io_tracking_value
3054 guint32 request_frame_num;
3055 guint32 response_frame_num;
3056 guint32 flow_frame_num;
3058 } pvfs2_io_tracking_value_t;
3061 pvfs2_io_tracking_equal(gconstpointer k1, gconstpointer k2)
3063 const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
3064 const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
3066 return (key1->tag == key2->tag);
3070 pvfs2_io_tracking_hash(gconstpointer k)
3072 const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
3074 return (key->tag >> 32) ^ ((guint32) key->tag);
3078 pvfs2_io_tracking_init(void)
3080 if (pvfs2_io_tracking_value_table != NULL)
3081 g_hash_table_destroy(pvfs2_io_tracking_value_table);
3083 pvfs2_io_tracking_value_table = g_hash_table_new(pvfs2_io_tracking_hash,
3084 pvfs2_io_tracking_equal);
3087 static pvfs2_io_tracking_value_t *
3088 pvfs2_io_tracking_new_with_tag(guint64 tag, guint32 num)
3090 pvfs2_io_tracking_value_t *value;
3091 pvfs2_io_tracking_key_t *newkey;
3093 newkey = (pvfs2_io_tracking_key_t *) se_alloc(sizeof(*newkey));
3094 memset(newkey, 0, sizeof(*newkey));
3097 value = se_alloc(sizeof(*value));
3098 memset(value, 0, sizeof(*value));
3100 g_hash_table_insert(pvfs2_io_tracking_value_table, newkey, value);
3102 value->request_frame_num = num;
3108 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
3109 gboolean dissect_other_as_continuation _U_)
3112 proto_item *item = NULL, *hitem = NULL;
3113 proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
3117 pvfs2_io_tracking_value_t *val = NULL;
3119 if (check_col(pinfo->cinfo, COL_PROTOCOL))
3120 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
3122 if (check_col(pinfo->cinfo, COL_INFO))
3123 col_clear(pinfo->cinfo, COL_INFO);
3127 item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, FALSE);
3130 pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
3133 proto_tree_add_text(pvfs_tree, tvb, 0, -1, "Version: 2");
3135 /* PVFS packet header is 24 bytes */
3136 hitem = proto_tree_add_text(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
3139 pvfs_htree = proto_item_add_subtree(hitem, ett_pvfs_hdr);
3142 proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, TRUE);
3145 /* TCP message mode (32-bit) */
3146 mode = tvb_get_letohl(tvb, offset);
3147 proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
3151 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
3154 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
3156 /* Lookahead to get server_op (invalid if frame contains flow data) */
3157 server_op = tvb_get_letohl(tvb, offset + 8);
3159 if (mode == TCP_MODE_UNEXP)
3161 /* Add entry to tracking table for PVFS_SERV_IO request */
3162 if ((server_op == PVFS_SERV_IO) && !pinfo->fd->flags.visited)
3163 val = pvfs2_io_tracking_new_with_tag(tag, pinfo->fd->num);
3167 pvfs2_io_tracking_key_t key;
3169 memset(&key, 0, sizeof(key));
3172 val = g_hash_table_lookup(pvfs2_io_tracking_value_table, &key);
3174 /* If this frame contains a known PVFS_SERV_IO tag, track it */
3175 if (val && !pinfo->fd->flags.visited)
3177 /* If response HAS NOT been seen, mark this frame as response */
3178 if (val->response_frame_num == 0)
3179 val->response_frame_num = pinfo->fd->num;
3182 /* If response HAS been seen, this frame is flow data */
3183 if (val->flow_frame_num == 0)
3184 val->flow_frame_num = pinfo->fd->num;
3189 if (val && (val->flow_frame_num == pinfo->fd->num))
3191 /* This frame is marked as being flow data */
3192 if (check_col(pinfo->cinfo, COL_INFO))
3193 col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
3195 proto_tree_add_text(pvfs_tree, tvb, offset, -1, "<data>");
3200 /* Extract common part of packet found in requests and responses */
3201 offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
3203 /* Update column info display */
3204 if (check_col(pinfo->cinfo, COL_INFO))
3206 col_set_str(pinfo->cinfo, COL_INFO,
3207 val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
3209 col_append_fstr(pinfo->cinfo, COL_INFO,
3210 (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
3213 /* TODO: handle all modes */
3214 if (mode == TCP_MODE_UNEXP)
3217 offset = dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
3221 /* TODO: re-examine this! */
3223 if (mode == TCP_MODE_REND)
3226 * TODO: move this code outside so it's common for requests and
3230 if (check_col(pinfo->cinfo, COL_INFO))
3231 col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
3237 offset = dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
3245 /* Register the protocol with Ethereal */
3247 proto_register_pvfs(void)
3249 static hf_register_info hf[] = {
3250 { &hf_pvfs_magic_nr,
3251 { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
3252 NULL, 0, "Magic Number", HFILL }},
3255 { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
3256 VALS(names_pvfs_mode), 0, "Mode", HFILL }},
3259 { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
3260 NULL, 0, "Tag", HFILL }},
3263 { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
3264 NULL, 0, "Size", HFILL }},
3266 { &hf_pvfs_release_number,
3267 { "Release Number", "pvfs.release_number", FT_UINT32, BASE_DEC,
3268 NULL, 0, "Release Number", HFILL }},
3270 { &hf_pvfs_encoding,
3271 { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
3272 VALS(names_pvfs_encoding), 0, "Encoding", HFILL }},
3274 { &hf_pvfs_server_op,
3275 { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
3276 VALS(names_pvfs_server_op), 0, "Server Operation", HFILL }},
3279 { "Handle", "pvfs.handle", FT_BYTES, BASE_HEX,
3280 NULL, 0, "Handle", HFILL }},
3283 { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
3284 NULL, 0, "File System ID", HFILL }},
3286 { &hf_pvfs_attrmask,
3287 { "attrmask", "pvfs.attrmask", FT_UINT32, BASE_HEX,
3288 NULL, 0, "Attribute Mask", HFILL }},
3291 { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
3292 VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
3295 { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
3296 VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
3299 { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
3300 VALS(names_pvfs_error), 0, "Result", HFILL }},
3303 { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, BASE_NONE,
3304 NULL, 0, "Access Time", HFILL }},
3306 { &hf_pvfs_atime_sec,
3307 { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
3308 NULL, 0, "Access Time (seconds)", HFILL }},
3310 { &hf_pvfs_atime_nsec,
3311 { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
3312 NULL, 0, "Access Time (microseconds)", HFILL }},
3315 { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
3316 NULL, 0, "Modify Time", HFILL }},
3318 { &hf_pvfs_mtime_sec,
3319 { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
3320 NULL, 0, "Modify Time (seconds)", HFILL }},
3322 { &hf_pvfs_mtime_nsec,
3323 { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
3324 NULL, 0, "Modify Time (microseconds)", HFILL }},
3327 { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, BASE_NONE,
3328 NULL, 0, "Creation Time", HFILL }},
3330 { &hf_pvfs_ctime_sec,
3331 { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
3332 NULL, 0, "Creation Time (seconds)", HFILL }},
3334 { &hf_pvfs_ctime_nsec,
3335 { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
3336 NULL, 0, "Creation Time (microseconds)", HFILL }},
3338 { &hf_pvfs_parent_atime,
3339 { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, BASE_NONE,
3340 NULL, 0, "Access Time", HFILL }},
3342 { &hf_pvfs_parent_atime_sec,
3343 { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
3344 NULL, 0, "Access Time (seconds)", HFILL }},
3346 { &hf_pvfs_parent_atime_nsec,
3347 { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
3348 NULL, 0, "Access Time (microseconds)", HFILL }},
3350 { &hf_pvfs_parent_mtime,
3351 { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, BASE_NONE,
3352 NULL, 0, "Modify Time", HFILL }},
3354 { &hf_pvfs_parent_mtime_sec,
3355 { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
3356 NULL, 0, "Modify Time (seconds)", HFILL }},
3358 { &hf_pvfs_parent_mtime_nsec,
3359 { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
3360 NULL, 0, "Modify Time (microseconds)", HFILL }},
3362 { &hf_pvfs_parent_ctime,
3363 { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, BASE_NONE,
3364 NULL, 0, "Creation Time", HFILL }},
3366 { &hf_pvfs_parent_ctime_sec,
3367 { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
3368 NULL, 0, "Creation Time (seconds)", HFILL }},
3370 { &hf_pvfs_parent_ctime_nsec,
3371 { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
3372 NULL, 0, "Creation Time (microseconds)", HFILL }},
3374 { &hf_pvfs_dirent_count,
3375 { "Dir Entry Count", "pvfs.dirent_count", FT_UINT64, BASE_DEC,
3376 NULL, 0, "Directory Entry Count", HFILL }},
3378 { &hf_pvfs_directory_version,
3379 { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
3380 NULL, 0, "Directory Version", HFILL }},
3383 { "Path", "pvfs.path", FT_STRING, BASE_DEC,
3384 NULL, 0, "Path", HFILL }},
3386 { &hf_pvfs_total_completed,
3387 { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
3388 NULL, 0, "Bytes Completed", HFILL }},
3391 { "Name", "pvfs.distribution.name", FT_STRING, BASE_DEC,
3392 NULL, 0, "Distribution Name", HFILL }},
3394 { &hf_pvfs_aggregate_size,
3395 { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
3396 NULL, 0, "Aggregate Size", HFILL }},
3399 { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
3400 VALS(names_pvfs_io_type), 0, "I/O Type", HFILL }},
3402 { &hf_pvfs_flowproto_type,
3403 { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
3404 VALS(names_pvfs_flowproto_type), 0, "Flow Protocol Type", HFILL }},
3406 { &hf_pvfs_server_param,
3407 { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
3408 VALS(names_pvfs_server_param), 0, "Server Parameter", HFILL }},
3410 { &hf_pvfs_prev_value,
3411 { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
3412 NULL, 0, "Previous Value", HFILL }},
3414 { &hf_pvfs_ram_free_bytes,
3415 { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
3416 NULL, 0, "RAM Free Bytes", HFILL }},
3418 { &hf_pvfs_bytes_available,
3419 { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
3420 NULL, 0, "Bytes Available", HFILL }},
3422 { &hf_pvfs_bytes_total,
3423 { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
3424 NULL, 0, "Bytes Total", HFILL }},
3426 { &hf_pvfs_ram_bytes_total,
3427 { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
3428 NULL, 0, "RAM Bytes Total", HFILL }},
3430 { &hf_pvfs_ram_bytes_free,
3431 { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
3432 NULL, 0, "RAM Bytes Free", HFILL }},
3434 { &hf_pvfs_load_average_1s,
3435 { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
3436 NULL, 0, "Load Average (1s)", HFILL }},
3438 { &hf_pvfs_load_average_5s,
3439 { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
3440 NULL, 0, "Load Average (5s)", HFILL }},
3442 { &hf_pvfs_load_average_15s,
3443 { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
3444 NULL, 0, "Load Average (15s)", HFILL }},
3446 { &hf_pvfs_uptime_seconds,
3447 { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
3448 NULL, 0, "Uptime (seconds)", HFILL }},
3450 { &hf_pvfs_handles_available,
3451 { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
3452 NULL, 0, "Handles Available", HFILL }},
3454 { &hf_pvfs_handles_total,
3455 { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
3456 NULL, 0, "Total Handles", HFILL }},
3459 * This is used when the field returns 64-bits but we're only interested
3460 * in the lower 32-bit bits.
3463 { "Unused", "", FT_UINT32, BASE_DEC,
3464 NULL, 0, "Unused", HFILL }},
3466 { &hf_pvfs_context_id,
3467 { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
3468 NULL, 0, "Context ID", HFILL }},
3471 { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
3472 NULL, 0, "Offset", HFILL }},
3475 { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
3476 NULL, 0, "Stride", HFILL }},
3479 { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
3480 NULL, 0, "ub", HFILL }},
3483 { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
3484 NULL, 0, "lb", HFILL }},
3486 { &hf_pvfs_end_time_ms,
3487 { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
3488 NULL, 0, "end_time_ms", HFILL }},
3490 { &hf_pvfs_cur_time_ms,
3491 { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
3492 NULL, 0, "cur_time_ms", HFILL }},
3494 { &hf_pvfs_start_time_ms,
3495 { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
3496 NULL, 0, "start_time_ms", HFILL }},
3498 { &hf_pvfs_bytes_written,
3499 { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
3500 NULL, 0, "bytes_written", HFILL }},
3502 { &hf_pvfs_bytes_read,
3503 { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
3504 NULL, 0, "bytes_read", HFILL }},
3506 { &hf_pvfs_metadata_write,
3507 { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
3508 NULL, 0, "metadata_write", HFILL }},
3510 { &hf_pvfs_metadata_read,
3511 { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
3512 NULL, 0, "metadata_read", HFILL }},
3515 { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
3516 BASE_DEC, NULL, 0, "Size of bstream", HFILL }},
3519 { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
3520 BASE_DEC, NULL, 0, "Number of keyvals", HFILL }},
3522 { &hf_pvfs_id_gen_t,
3523 { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
3524 NULL, 0, "id_gen_t", HFILL }},
3526 { &hf_pvfs_attribute_key,
3527 { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_DEC,
3528 NULL, 0, "Attribute key", HFILL }},
3530 { &hf_pvfs_attribute_value,
3531 { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_DEC,
3532 NULL, 0, "Attribute value", HFILL }},
3534 { &hf_pvfs_strip_size,
3535 { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
3536 NULL, 0, "Strip size (bytes)", HFILL }},
3538 /* TODO: need description */
3540 { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
3541 NULL, 0, "ereg", HFILL }},
3543 /* TODO: need description */
3545 { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
3546 NULL, 0, "sreg", HFILL }},
3548 { &hf_pvfs_num_eregs,
3549 { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
3550 NULL, 0, "Number of eregs", HFILL }},
3552 { &hf_pvfs_num_blocks,
3553 { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
3554 NULL, 0, "Number of blocks", HFILL }},
3556 { &hf_pvfs_num_contig_chunks,
3557 { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
3558 BASE_DEC, NULL, 0, "Number of contig_chunks", HFILL }},
3560 { &hf_pvfs_server_nr,
3561 { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
3562 NULL, 0, "Server #", HFILL }},
3564 { &hf_pvfs_server_count,
3565 { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
3566 NULL, 0, "Number of servers", HFILL }},
3568 { &hf_pvfs_fh_length,
3569 { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
3570 NULL, 0, "file handle length", HFILL }},
3573 { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
3574 NULL, 0, "file handle hash", HFILL }},
3577 /* Setup protocol subtree array */
3578 static gint *ett[] = {
3581 &ett_pvfs_credentials,
3582 &ett_pvfs_server_config,
3583 &ett_pvfs_server_config_branch,
3586 &ett_pvfs_extent_array_tree,
3587 &ett_pvfs_extent_item,
3589 &ett_pvfs_attr_tree,
3590 &ett_pvfs_distribution,
3591 &ett_pvfs_mgmt_perf_stat,
3592 &ett_pvfs_mgmt_dspace_info,
3596 module_t *pvfs_module;
3598 /* Register the protocol name and description */
3599 proto_pvfs = proto_register_protocol("Parallel Virtual File System",
3603 * Required function calls to register the header fields and
3607 proto_register_field_array(proto_pvfs, hf, array_length(hf));
3608 proto_register_subtree_array(ett, array_length(ett));
3610 register_init_routine(pvfs2_io_tracking_init);
3612 pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
3613 prefs_register_bool_preference(pvfs_module, "desegment",
3614 "Reassemble PVFS messages spanning multiple TCP segments",
3615 "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
3616 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3621 proto_reg_handoff_pvfs(void)
3623 dissector_handle_t pvfs_handle;
3625 pvfs_handle = new_create_dissector_handle(dissect_pvfs_heur, proto_pvfs);
3626 dissector_add("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
3628 heur_dissector_add("tcp", dissect_pvfs_heur, proto_pvfs);