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 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
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.
44 #include <epan/packet.h>
45 #include <epan/prefs.h>
46 #include <epan/emem.h>
47 #include <epan/strutil.h>
48 #include "packet-tcp.h"
50 #define TCP_PORT_PVFS2 3334
52 #define PVFS2_FH_LENGTH 8
54 /* Header incl. magic number, mode, tag, size */
55 #define BMI_HEADER_SIZE 24
57 /* desegmentation of PVFS over TCP */
58 static gboolean pvfs_desegment = TRUE;
60 /* Forward declaration we need below */
61 void proto_reg_handoff_pvfs(void);
63 /* Initialize the protocol and registered fields */
64 static int proto_pvfs = -1;
65 static int hf_pvfs_magic_nr = -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_dirent_count = -1;
97 static int hf_pvfs_directory_version = -1;
98 static int hf_pvfs_path = -1;
99 static int hf_pvfs_total_completed = -1;
100 static int hf_pvfs_io_dist = -1;
101 static int hf_pvfs_aggregate_size = -1;
102 static int hf_pvfs_io_type = -1;
103 static int hf_pvfs_flowproto_type = -1;
104 static int hf_pvfs_server_param = -1;
105 static int hf_pvfs_prev_value = -1;
106 static int hf_pvfs_ram_free_bytes = -1;
107 static int hf_pvfs_bytes_available = -1;
108 static int hf_pvfs_bytes_total = -1;
109 static int hf_pvfs_ram_bytes_total = -1;
110 static int hf_pvfs_ram_bytes_free = -1;
111 static int hf_pvfs_load_average_1s = -1;
112 static int hf_pvfs_load_average_5s = -1;
113 static int hf_pvfs_load_average_15s = -1;
114 static int hf_pvfs_uptime_seconds = -1;
115 static int hf_pvfs_handles_available = -1;
116 static int hf_pvfs_handles_total = -1;
117 static int hf_pvfs_unused = -1;
118 static int hf_pvfs_context_id = -1;
119 static int hf_pvfs_offset = -1;
120 static int hf_pvfs_stride = -1;
121 static int hf_pvfs_lb = -1;
122 static int hf_pvfs_ub = -1;
123 static int hf_pvfs_end_time_ms = -1;
124 static int hf_pvfs_cur_time_ms = -1;
125 static int hf_pvfs_start_time_ms = -1;
126 static int hf_pvfs_bytes_written = -1;
127 static int hf_pvfs_bytes_read = -1;
128 static int hf_pvfs_metadata_write = -1;
129 static int hf_pvfs_metadata_read = -1;
130 static int hf_pvfs_b_size = -1;
131 static int hf_pvfs_k_size = -1;
132 static int hf_pvfs_id_gen_t = -1;
133 static int hf_pvfs_attribute_key = -1;
134 static int hf_pvfs_attribute_value = -1;
135 static int hf_pvfs_strip_size = -1;
136 static int hf_pvfs_ereg = -1;
137 static int hf_pvfs_sreg = -1;
138 static int hf_pvfs_num_eregs = -1;
139 static int hf_pvfs_num_blocks = -1;
140 static int hf_pvfs_num_contig_chunks = -1;
141 static int hf_pvfs_server_nr = -1;
142 static int hf_pvfs_server_count = -1;
143 static int hf_pvfs_fh_length = -1;
144 static int hf_pvfs_fh_hash = -1;
146 /* Initialize the subtree pointers */
147 static gint ett_pvfs = -1;
148 static gint ett_pvfs_hdr = -1;
149 static gint ett_pvfs_credentials = -1;
150 static gint ett_pvfs_server_config = -1;
151 static gint ett_pvfs_server_config_branch = -1;
152 static gint ett_pvfs_attrmask = -1;
153 static gint ett_pvfs_time = -1;
154 static gint ett_pvfs_extent_array_tree = -1;
155 static gint ett_pvfs_extent_item = -1;
156 static gint ett_pvfs_string = -1;
157 static gint ett_pvfs_attr_tree = -1;
158 static gint ett_pvfs_distribution = -1;
159 static gint ett_pvfs_mgmt_perf_stat = -1;
160 static gint ett_pvfs_mgmt_dspace_info = -1;
161 static gint ett_pvfs_attr = -1;
162 static gint ett_pvfs_fh = -1;
164 #define BMI_MAGIC_NR 51903
166 static const value_string names_pvfs_mode[] =
168 #define TCP_MODE_IMMED 1
169 { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
170 #define TCP_MODE_UNEXP 2
171 { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
172 #define TCP_MODE_EAGER 4
173 { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
174 #define TCP_MODE_REND 8
175 { TCP_MODE_REND, "TCP_MODE_REND" },
179 static const value_string names_pvfs_encoding[] =
181 #define PVFS_ENCODING_DIRECT 1
182 { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
183 #define PVFS_ENCODING_LE_BFIELD 2
184 { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
185 #define PVFS_ENCODING_XDR 3
186 { PVFS_ENCODING_XDR, "ENCODING_XDR" },
190 static const value_string names_pvfs_io_type[] =
192 #define PVFS_IO_READ 1
193 { PVFS_IO_READ, "PVFS_IO_READ" },
194 #define PVFS_IO_WRITE 2
195 { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
199 static const value_string names_pvfs_flowproto_type[] =
201 #define FLOWPROTO_DUMP_OFFSETS 1
202 { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
203 #define FLOWPROTO_BMI_CACHE 2
204 { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
205 #define FLOWPROTO_MULTIQUEUE 3
206 { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
210 static const value_string names_pvfs_server_param[] =
212 #define PVFS_SERV_PARAM_INVALID 0
213 { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
214 #define PVFS_SERV_PARAM_GOSSIP_MASK 1
215 { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
216 #define PVFS_SERV_PARAM_FSID_CHECK 2
217 { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
218 #define PVFS_SERV_PARAM_ROOT_CHECK 3
219 { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
220 #define PVFS_SERV_PARAM_MODE 4
221 { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
222 #define PVFS_SERV_PARAM_EVENT_ON 5
223 { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
224 #define PVFS_SERV_PARAM_EVENT_MASKS 6
225 { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
229 static const value_string names_pvfs_server_mode[] =
231 #define PVFS_SERVER_NORMAL_MODE 1
232 { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
233 #define PVFS_SERVER_ADMIN_MODE 2
234 { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
238 /* Forward declaration */
240 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
241 gboolean dissect_other_as_continuation);
244 static void dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
246 dissect_pvfs_common(tvb, pinfo, tree, FALSE);
250 static guint get_pvfs_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
255 * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
257 plen = tvb_get_letohl(tvb, offset + 16);
263 dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
265 guint32 magic_nr, mode;
268 /* verify that this is indeed PVFS and that it looks sane */
269 if(tvb_length(tvb)<24){
270 /* too few bytes remaining to verify the header */
274 /* validate the magic number */
275 magic_nr = tvb_get_letohl(tvb, 0);
276 if(magic_nr!=BMI_MAGIC_NR){
280 /* Validate the TCP message mode (32-bit) */
281 mode = tvb_get_letohl(tvb, 4);
289 /* invalid mode, not a PVFS packet */
293 /* validate the size : assume size must be >0 and less than 1000000 */
294 size=tvb_get_letohl(tvb, 20);
296 size|=tvb_get_letohl(tvb, 16);
297 if((size>1000000)||(size==0)){
301 tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
304 return tvb_length(tvb);
307 static const value_string names_pvfs_server_op[] =
309 #define PVFS_SERV_INVALID 0
310 { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
311 #define PVFS_SERV_CREATE 1
312 { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
313 #define PVFS_SERV_REMOVE 2
314 { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
315 #define PVFS_SERV_IO 3
316 { PVFS_SERV_IO, "PVFS_SERV_IO" },
317 #define PVFS_SERV_GETATTR 4
318 { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
319 #define PVFS_SERV_SETATTR 5
320 { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
321 #define PVFS_SERV_LOOKUP_PATH 6
322 { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
323 #define PVFS_SERV_CRDIRENT 7
324 { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
325 #define PVFS_SERV_RMDIRENT 8
326 { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
327 #define PVFS_SERV_CHDIRENT 9
328 { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
329 #define PVFS_SERV_TRUNCATE 10
330 { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
331 #define PVFS_SERV_MKDIR 11
332 { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
333 #define PVFS_SERV_READDIR 12
334 { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
335 #define PVFS_SERV_GETCONFIG 13
336 { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
337 #define PVFS_SERV_WRITE_COMPLETION 14
338 { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
339 #define PVFS_SERV_FLUSH 15
340 { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
341 #define PVFS_SERV_MGMT_SETPARAM 16
342 { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
343 #define PVFS_SERV_MGMT_NOOP 17
344 { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
345 #define PVFS_SERV_STATFS 18
346 { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
347 #define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
348 { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
349 #define PVFS_SERV_MGMT_PERF_MON 20
350 { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
351 #define PVFS_SERV_MGMT_ITERATE_HANDLES 21
352 { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
353 #define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
354 { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
355 #define PVFS_SERV_MGMT_EVENT_MON 23
356 { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
357 #define PVFS_SERV_MGMT_REMOVE_OBJECT 24
358 { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
359 #define PVFS_SERV_MGMT_REMOVE_DIRENT 25
360 { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
361 #define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
362 { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
363 #define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
364 { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
365 #define PVFS_SERV_PROTO_ERROR 28
366 { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
367 #define PVFS_SERV_GETEATTR 29
368 { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
369 #define PVFS_SERV_SETEATTR 30
370 { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
371 #define PVFS_SERV_DELEATTR 31
372 { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
376 /* special bits used to differentiate PVFS error codes from system
379 #define PVFS_ERROR_BIT (1 << 30)
381 /* a shorthand to make the error code definitions more readable */
382 #define E(num) (num|PVFS_ERROR_BIT)
384 static const value_string names_pvfs_error[] = {
386 #define PVFS_EPERM E(1) /* Operation not permitted */
387 { PVFS_EPERM, "PVFS_EPERM" },
388 #define PVFS_ENOENT E(2) /* No such file or directory */
389 { PVFS_ENOENT, "PVFS_ENOENT" },
390 #define PVFS_EINTR E(3) /* Interrupted system call */
391 { PVFS_EINTR, "PVFS_EINTR" },
392 #define PVFS_EIO E(4) /* I/O error */
393 { PVFS_EIO, "PVFS_EIO" },
394 #define PVFS_ENXIO E(5) /* No such device or address */
395 { PVFS_ENXIO, "PVFS_ENXIO" },
396 #define PVFS_EBADF E(6) /* Bad file number */
397 { PVFS_EBADF, "PVFS_EBADF" },
398 #define PVFS_EAGAIN E(7) /* Try again */
399 { PVFS_EAGAIN, "PVFS_EAGAIN" },
400 #define PVFS_ENOMEM E(8) /* Out of memory */
401 { PVFS_ENOMEM, "PVFS_ENOMEM" },
402 #define PVFS_EFAULT E(9) /* Bad address */
403 { PVFS_EFAULT, "PVFS_EFAULT" },
404 #define PVFS_EBUSY E(10) /* Device or resource busy */
405 { PVFS_EBUSY, "PVFS_EBUSY" },
406 #define PVFS_EEXIST E(11) /* File exists */
407 { PVFS_EEXIST, "PVFS_EEXIST" },
408 #define PVFS_ENODEV E(12) /* No such device */
409 { PVFS_ENODEV, "PVFS_ENODEV" },
410 #define PVFS_ENOTDIR E(13) /* Not a directory */
411 { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
412 #define PVFS_EISDIR E(14) /* Is a directory */
413 { PVFS_EISDIR, "PVFS_EISDIR" },
414 #define PVFS_EINVAL E(15) /* Invalid argument */
415 { PVFS_EINVAL, "PVFS_EINVAL" },
416 #define PVFS_EMFILE E(16) /* Too many open files */
417 { PVFS_EMFILE, "PVFS_EMFILE" },
418 #define PVFS_EFBIG E(17) /* File too large */
419 { PVFS_EFBIG, "PVFS_EFBIG" },
420 #define PVFS_ENOSPC E(18) /* No space left on device */
421 { PVFS_ENOSPC, "PVFS_ENOSPC" },
422 #define PVFS_EROFS E(19) /* Read-only file system */
423 { PVFS_EROFS, "PVFS_EROFS" },
424 #define PVFS_EMLINK E(20) /* Too many links */
425 { PVFS_EMLINK, "PVFS_EMLINK" },
426 #define PVFS_EPIPE E(21) /* Broken pipe */
427 { PVFS_EPIPE, "PVFS_EPIPE" },
428 #define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
429 { PVFS_EDEADLK, "PVFS_EDEADLK" },
430 #define PVFS_ENAMETOOLONG E(23) /* File name too long */
431 { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
432 #define PVFS_ENOLCK E(24) /* No record locks available */
433 { PVFS_ENOLCK, "PVFS_ENOLCK" },
434 #define PVFS_ENOSYS E(25) /* Function not implemented */
435 { PVFS_ENOSYS, "PVFS_ENOSYS" },
436 #define PVFS_ENOTEMPTY E(26) /* Directory not empty */
437 { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
438 #define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
439 { PVFS_ELOOP, "PVFS_ELOOP" },
440 #define PVFS_EWOULDBLOCK E(28) /* Operation would block */
441 { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
442 #define PVFS_ENOMSG E(29) /* No message of desired type */
443 { PVFS_ENOMSG, "PVFS_ENOMSG" },
444 #define PVFS_EUNATCH E(30) /* Protocol driver not attached */
445 { PVFS_EUNATCH, "PVFS_EUNATCH" },
446 #define PVFS_EBADR E(31) /* Invalid request descriptor */
447 { PVFS_EBADR, "PVFS_EBADR" },
448 #define PVFS_EDEADLOCK E(32)
449 { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
450 #define PVFS_ENODATA E(33) /* No data available */
451 { PVFS_ENODATA, "PVFS_ENODATA" },
452 #define PVFS_ETIME E(34) /* Timer expired */
453 { PVFS_ETIME, "PVFS_ETIME" },
454 #define PVFS_ENONET E(35) /* Machine is not on the network */
455 { PVFS_ENONET, "PVFS_ENONET" },
456 #define PVFS_EREMOTE E(36) /* Object is remote */
457 { PVFS_EREMOTE, "PVFS_EREMOTE" },
458 #define PVFS_ECOMM E(37) /* Communication error on send */
459 { PVFS_ECOMM, "PVFS_ECOMM" },
460 #define PVFS_EPROTO E(38) /* Protocol error */
461 { PVFS_EPROTO, "PVFS_EPROTO" },
462 #define PVFS_EBADMSG E(39) /* Not a data message */
463 { PVFS_EBADMSG, "PVFS_EBADMSG" },
464 #define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
465 { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
466 #define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
467 { PVFS_ERESTART, "PVFS_ERESTART" },
468 #define PVFS_EMSGSIZE E(42) /* Message too long */
469 { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
470 #define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
471 { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
472 #define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
473 { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
474 #define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
475 { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
476 #define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
477 { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
478 #define PVFS_EADDRINUSE E(47) /* Address already in use */
479 { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
480 #define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
481 { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
482 #define PVFS_ENETDOWN E(49) /* Network is down */
483 { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
484 #define PVFS_ENETUNREACH E(50) /* Network is unreachable */
485 { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
486 #define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
487 { PVFS_ENETRESET, "PVFS_ENETRESET" },
488 #define PVFS_ENOBUFS E(52) /* No buffer space available */
489 { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
490 #define PVFS_ETIMEDOUT E(53) /* Connection timed out */
491 { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
492 #define PVFS_ECONNREFUSED E(54) /* Connection refused */
493 { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
494 #define PVFS_EHOSTDOWN E(55) /* Host is down */
495 { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
496 #define PVFS_EHOSTUNREACH E(56) /* No route to host */
497 { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
498 #define PVFS_EALREADY E(57) /* Operation already in progress */
499 { PVFS_EALREADY, "PVFS_EALREADY" },
500 #define PVFS_EACCES E(58) /* Operation already in progress */
501 { PVFS_EACCES, "PVFS_EACCES" },
506 dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
510 const char *errmsg = NULL;
512 err = tvb_get_letohl(tvb, offset);
513 proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
516 if ((err != 0) && check_col(pinfo->cinfo, COL_INFO))
518 errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
519 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
526 dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
529 proto_item *item = NULL;
530 proto_tree *hcred_tree = NULL;
531 guint32 uid = 0, gid = 0;
533 uid = tvb_get_letohl(tvb, offset);
534 gid = tvb_get_letohl(tvb, offset + 4);
538 item = proto_tree_add_text(parent_tree, tvb, offset, 8,
539 "Credentials (UID: %d, GID: %d)", uid, gid);
542 hcred_tree = proto_item_add_subtree(item, ett_pvfs_credentials);
546 proto_tree_add_text(hcred_tree, tvb, offset, 4, "UID: %d", uid);
550 proto_tree_add_text(hcred_tree, tvb, offset, 4, "GID: %d", gid);
556 static const value_string names_pvfs_attr[] =
558 #define PVFS_ATTR_COMMON_UID (1 << 0)
559 #define PVFS_ATTR_BIT_COMMON_UID 0
560 { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
562 #define PVFS_ATTR_COMMON_GID (1 << 1)
563 #define PVFS_ATTR_BIT_COMMON_GID 1
564 { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
566 #define PVFS_ATTR_COMMON_PERM (1 << 2)
567 #define PVFS_ATTR_BIT_COMMON_PERM 2
568 { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
570 #define PVFS_ATTR_COMMON_ATIME (1 << 3)
571 #define PVFS_ATTR_BIT_COMMON_ATIME 3
572 { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
574 #define PVFS_ATTR_COMMON_CTIME (1 << 4)
575 #define PVFS_ATTR_BIT_COMMON_CTIME 4
576 { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
578 #define PVFS_ATTR_COMMON_MTIME (1 << 5)
579 #define PVFS_ATTR_BIT_COMMON_MTIME 5
580 { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
582 #define PVFS_ATTR_COMMON_TYPE (1 << 6)
583 #define PVFS_ATTR_BIT_COMMON_TYPE 6
584 { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
587 #define PVFS_ATTR_COMMON_ALL \
588 (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
589 PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
590 PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
591 PVFS_ATTR_COMMON_TYPE)
594 /* internal attribute masks for metadata objects */
595 #define PVFS_ATTR_META_DIST (1 << 10)
596 #define PVFS_ATTR_BIT_META_DIST 10
597 { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
599 #define PVFS_ATTR_META_DFILES (1 << 11)
600 #define PVFS_ATTR_BIT_META_DFILES 11
601 { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
604 #define PVFS_ATTR_META_ALL \
605 (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
608 /* internal attribute masks for datafile objects */
609 #define PVFS_ATTR_DATA_SIZE (1 << 15)
610 #define PVFS_ATTR_BIT_DATA_SIZE 15
611 { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
614 #define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
617 /* internal attribute masks for symlink objects */
618 #define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
619 #define PVFS_ATTR_BIT_SYMLINK_TARGET 18
620 { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
623 #define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
626 /* internal attribute masks for directory objects */
627 #define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
628 #define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
629 { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
632 #define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
635 /* attribute masks used by system interface callers */
636 #define PVFS_ATTR_SYS_SIZE (1 << 20)
637 #define PVFS_ATTR_BIT_SYS_SIZE 20
638 { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
640 #define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
641 #define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
642 { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
644 #define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
645 #define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
646 { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
648 #define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
649 #define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
650 { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
653 #define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
654 #define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
655 #define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
656 #define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
657 #define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
658 #define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
659 #define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
665 #define PVFS_ATTR_SYS_ALL \
666 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
667 PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
668 PVFS_ATTR_SYS_DIRENT_COUNT)
670 #define PVFS_ATTR_SYS_ALL_NOSIZE \
671 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
672 PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
674 #define PVFS_ATTR_SYS_ALL_SETABLE \
675 (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
680 dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
683 guint32 attrmask = 0, i = 0;
684 proto_item *attritem = NULL;
685 proto_tree *attrtree = NULL;
687 attrmask = tvb_get_letohl(tvb, offset);
689 attritem = proto_tree_add_text(tree, tvb, offset, 4,
690 "Attribute Mask: %d", attrmask);
693 attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
695 for (i = 0; i < 32; i++)
697 if (attrmask & (1 << i))
698 proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
704 *pattrmask = attrmask;
709 static const value_string names_pvfs_ds_type[] = {
710 #define PVFS_TYPE_NONE 0
711 { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
712 #define PVFS_TYPE_METAFILE (1 << 0)
713 { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
714 #define PVFS_TYPE_DATAFILE (1 << 1)
715 { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
716 #define PVFS_TYPE_DIRECTORY (1 << 2)
717 { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
718 #define PVFS_TYPE_SYMLINK (1 << 3)
719 { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
720 #define PVFS_TYPE_DIRDATA (1 << 4)
721 { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
726 dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
731 ds_type = tvb_get_letohl(tvb, offset);
734 proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
744 #define roundup4(x) (((x) + 3) & ~3)
745 #define roundup8(x) (((x) + 7) & ~7)
748 dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
750 packet_info *pinfo _U_,
752 gboolean fixed_length, guint32 length,
753 gboolean string_data, char const **string_buffer_ret)
756 proto_item *string_item = NULL;
757 proto_tree *string_tree = NULL;
759 guint32 string_length;
760 guint32 string_length_full;
761 guint32 string_length_packet;
762 guint32 string_length_captured;
763 guint32 string_length_copy;
767 guint32 fill_length_packet;
768 guint32 fill_length_captured;
769 guint32 fill_length_copy;
773 char *string_buffer = NULL;
774 const char *string_buffer_print = NULL;
777 string_length = length;
778 data_offset = offset;
780 string_length = tvb_get_letohl(tvb,offset+0);
781 data_offset = offset + 4;
784 * Variable-length strings include NULL terminator on-the-wire but
785 * NULL terminator is not included in string length.
792 string_length_captured = tvb_length_remaining(tvb, data_offset);
793 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
796 * Strangeness... the protocol basically says that the length plus
797 * the string must be padded out to an 8-byte boundary.
801 string_length_full = roundup4(string_length);
803 string_length_full = roundup8(4 + string_length);
805 if (string_length_captured < string_length) {
806 /* truncated string */
807 string_length_copy = string_length_captured;
810 fill_length_copy = 0;
812 if (string_length_packet < string_length)
813 exception = ReportedBoundsError;
815 exception = BoundsError;
818 /* full string data */
819 string_length_copy = string_length;
822 fill_length = string_length_full - string_length;
824 fill_length = string_length_full - string_length - 4;
826 fill_length_captured = tvb_length_remaining(tvb,
827 data_offset + string_length);
828 fill_length_packet = tvb_reported_length_remaining(tvb,
829 data_offset + string_length);
831 if (fill_length_captured < fill_length) {
832 /* truncated fill bytes */
833 fill_length_copy = fill_length_packet;
835 if (fill_length_packet < fill_length)
836 exception = ReportedBoundsError;
838 exception = BoundsError;
841 /* full fill bytes */
842 fill_length_copy = fill_length;
850 tmpstr = (char *) tvb_get_ephemeral_string(tvb, data_offset,
853 string_buffer = memcpy(ep_alloc(string_length_copy+1), tmpstr, string_length_copy);
855 string_buffer = (char *) tvb_memcpy(tvb,
856 ep_alloc(string_length_copy+1), data_offset, string_length_copy);
859 string_buffer[string_length_copy] = '\0';
861 /* calculate a nice printable string */
863 if (string_length != string_length_copy) {
866 guint16 string_buffer_size = 0;
868 formatted = format_text((guint8 *)string_buffer,
869 (int)strlen(string_buffer));
871 string_buffer_size = (guint16)strlen(formatted) + 12 + 1;
873 /* alloc maximum data area */
874 string_buffer_print = (char*) ep_alloc(string_buffer_size);
875 /* copy over the data */
876 g_snprintf((char *)string_buffer_print, string_buffer_size,
877 "%s<TRUNCATED>", formatted);
878 /* append <TRUNCATED> */
879 /* This way, we get the TRUNCATED even
880 in the case of totally wrong packets,
881 where \0 are inside the string.
882 TRUNCATED will appear at the
883 first \0 or at the end (where we
884 put the securing \0).
887 string_buffer_print="<DATA><TRUNCATED>";
891 string_buffer_print =
892 ep_strdup(format_text((guint8 *) string_buffer,
893 (int)strlen(string_buffer)));
895 string_buffer_print="<DATA>";
899 string_buffer_print="<EMPTY>";
903 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
904 "%s: %s", proto_registrar_get_name(hfindex),
905 string_buffer_print);
908 string_tree = proto_item_add_subtree(string_item,
913 proto_tree_add_text(string_tree, tvb,offset+0,4,
914 "length: %u (excl. NULL terminator)", string_length - 1);
920 proto_tree_add_string_format(string_tree,
921 hfindex, tvb, offset, string_length_copy,
923 "contents: %s", string_buffer_print);
925 proto_tree_add_bytes_format(string_tree,
926 hfindex, tvb, offset, string_length_copy,
927 (guint8 *) string_buffer,
928 "contents: %s", string_buffer_print);
932 offset += string_length_copy;
936 if (fill_truncated) {
937 proto_tree_add_text(string_tree, tvb,
938 offset,fill_length_copy,
939 "fill bytes: opaque data<TRUNCATED>");
942 proto_tree_add_text(string_tree, tvb,
943 offset,fill_length_copy,
944 "fill bytes: opaque data");
947 offset += fill_length_copy;
951 proto_item_set_end(string_item, tvb, offset);
953 if (string_buffer_ret != NULL)
954 *string_buffer_ret = string_buffer_print;
957 * If the data was truncated, throw the appropriate exception,
958 * so that dissection stops and the frame is properly marked.
967 dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
968 int offset, const char **string_buffer_ret)
970 return dissect_pvfs_opaque_data(tvb, offset, tree, NULL, hfindex,
971 FALSE, 0, TRUE, string_buffer_ret);
975 dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
981 bytes_left = PVFS2_FH_LENGTH;
983 while (bytes_left != 0) {
985 if (sublen > bytes_left)
987 proto_tree_add_text(tree, tvb, offset, sublen,
989 first_line ? "data: " :
991 tvb_bytes_to_str(tvb,offset,sublen));
992 bytes_left -= sublen;
999 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1000 proto_tree *tree, guint32 *hash)
1005 /* Not all bytes there. Any attempt to deduce the type would be
1007 if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
1010 /* create a semiunique hash value for the filehandle */
1011 for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
1013 val = tvb_get_ntohl(tvb, offset+i);
1018 proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
1024 /* TODO: add file name snooping code here */
1027 dissect_fhandle_data_unknown(tvb, offset, tree);
1031 dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
1032 proto_tree *tree, const char *name, guint32 *hash)
1034 proto_item* fitem = NULL;
1035 proto_tree* ftree = NULL;
1039 fitem = proto_tree_add_text(tree, tvb, offset, PVFS2_FH_LENGTH,
1043 ftree = proto_item_add_subtree(fitem, ett_pvfs_fh);
1046 /* TODO: add fh to file name snooping code here */
1048 proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
1051 dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
1053 offset += PVFS2_FH_LENGTH;
1059 dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
1060 packet_info *pinfo, guint32 nCount)
1062 proto_item *extent_item = NULL;
1063 proto_tree *extent_tree = NULL;
1067 extent_item = proto_tree_add_text(tree, tvb, offset, 8,
1071 extent_tree = proto_item_add_subtree(extent_item,
1072 ett_pvfs_extent_item);
1076 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
1080 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
1087 dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
1090 guint32 extent_count = 0;
1092 proto_item *extent_array_item = NULL;
1093 proto_tree *extent_array_tree = NULL;
1096 extent_count = tvb_get_letohl(tvb, offset);
1099 extent_array_item = proto_tree_add_text(tree, tvb, offset, 4,
1100 "Handle Extent Array (count = %d)", extent_count);
1104 if (extent_count > 0)
1106 if (extent_array_item)
1107 extent_array_tree = proto_item_add_subtree(extent_array_item,
1108 ett_pvfs_extent_array_tree);
1110 /* Add extent array items */
1111 for (nCount = 0; nCount < extent_count; nCount++)
1112 offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
1120 dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
1121 int hf_time, int hf_time_sec, int hf_time_nsec)
1126 proto_item *time_item = NULL;
1127 proto_tree *time_tree = NULL;
1129 ts.secs = seconds = tvb_get_letohl(tvb, offset);
1130 ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
1134 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
1137 time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
1142 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
1143 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4,
1152 int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
1153 int hfindex, guint64 *pvalue)
1157 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1158 tvb_get_letohl(tvb, offset);
1160 proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
1168 /* Taken from pvfs2-dist-simple-stripe.h */
1169 #define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
1170 #define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
1173 dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset)
1175 proto_item *dist_item = NULL;
1176 proto_tree *dist_tree = NULL;
1177 guint32 distlen = 0;
1178 char *tmpstr = NULL;
1179 guint8 issimplestripe = 0;
1181 /* Get distribution name length */
1182 distlen = tvb_get_letohl(tvb, offset);
1184 /* Get distribution name */
1185 tmpstr = (char *) tvb_get_ephemeral_string(tvb, offset + 4, distlen);
1191 /* 'distlen' does not include the NULL terminator */
1192 total_len = roundup8(4 + distlen + 1);
1194 if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
1195 (g_ascii_strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
1198 /* Parameter for 'simple_stripe' is 8 bytes */
1204 dist_item = proto_tree_add_text(tree, tvb, offset, total_len + 8,
1205 "Distribution: %s", tmpstr);
1208 dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
1212 offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
1215 /* TODO: only one distribution type is currently supported */
1217 offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
1218 hf_pvfs_strip_size, NULL);
1226 dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
1229 guint32 dfile_count, i;
1232 dfile_count = tvb_get_letohl(tvb, offset);
1233 proto_tree_add_text(tree, tvb, offset, 4, "dfile_count: %d",
1237 for (i = 0; i < dfile_count; i++)
1238 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1244 dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
1248 guint32 attrmask = 0;
1249 proto_item *attr_item = NULL;
1250 proto_tree *attr_tree = NULL;
1254 attr_item = proto_tree_add_text(tree, tvb, offset, -1, "Attributes");
1257 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr_tree);
1261 proto_tree_add_text(attr_tree, tvb, offset, 4, "UID: %d",
1262 tvb_get_letohl(tvb, offset));
1266 proto_tree_add_text(attr_tree, tvb, offset, 4, "GID: %d",
1267 tvb_get_letohl(tvb, offset));
1271 proto_tree_add_text(attr_tree, tvb, offset, 4, "Permissions: %o",
1272 tvb_get_letohl(tvb, offset));
1278 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
1279 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1282 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
1283 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1286 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
1287 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1290 offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
1293 offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
1295 if (attrmask & PVFS_ATTR_META_DIST)
1297 offset = dissect_pvfs_distribution(tvb, attr_tree, offset);
1299 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1303 if (attrmask & PVFS_ATTR_META_DFILES)
1305 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1309 if (attrmask & PVFS_ATTR_DATA_SIZE)
1311 offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
1316 if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
1318 /* target_path_len */
1319 proto_tree_add_text(attr_tree, tvb, offset, 4,
1320 "target_path_len: %d", tvb_get_letohl(tvb, offset));
1326 offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
1331 if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
1333 offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
1334 hf_pvfs_size, NULL);
1345 dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1347 proto_tree_add_uint(tree, hf_pvfs_io_type, tvb, offset, 4,
1348 tvb_get_letohl(tvb, offset));
1355 dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1357 proto_tree_add_uint(tree, hf_pvfs_flowproto_type, tvb, offset, 4,
1358 tvb_get_letohl(tvb, offset));
1365 dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
1368 guint32 server_param = 0;
1372 server_param = tvb_get_letohl(tvb, offset);
1373 proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
1377 switch (server_param)
1379 case PVFS_SERV_PARAM_MODE:
1380 lowpart = tvb_get_letohl(tvb, offset);
1382 proto_tree_add_text(tree, tvb, offset, 8,
1383 "Server Mode: %s (%u)",
1384 val_to_str(lowpart, names_pvfs_server_mode, "%u"), lowpart);
1387 case PVFS_SERV_PARAM_FSID_CHECK:
1388 lowpart = tvb_get_letohl(tvb, offset);
1389 proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4, lowpart);
1390 proto_tree_add_uint(tree, hf_pvfs_unused, tvb, offset + 4, 4,
1391 tvb_get_letohl(tvb, offset + 4));
1394 case PVFS_SERV_PARAM_ROOT_CHECK:
1395 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1405 dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1408 proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4,
1409 tvb_get_letohl(tvb, offset));
1417 * =======================================================================
1419 * =======================================================================
1423 dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1427 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1430 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
1434 offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
1440 dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1444 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1447 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1453 dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
1459 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1460 tvb_get_letohl(tvb, offset);
1461 proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
1464 /* TODO: num_eregs */
1465 proto_tree_add_uint(tree, hf_pvfs_num_eregs, tvb, offset, 4,
1466 tvb_get_letohl(tvb, offset));
1469 /* TODO: num_blocks */
1470 proto_tree_add_uint(tree, hf_pvfs_num_blocks, tvb, offset, 4,
1471 tvb_get_letohl(tvb, offset));
1475 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1476 tvb_get_letohl(tvb, offset);
1477 proto_tree_add_uint64(tree, hf_pvfs_stride, tvb, offset, 8, val);
1481 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1482 tvb_get_letohl(tvb, offset);
1483 proto_tree_add_uint64(tree, hf_pvfs_ub, tvb, offset, 8, val);
1487 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1488 tvb_get_letohl(tvb, offset);
1489 proto_tree_add_uint64(tree, hf_pvfs_lb, tvb, offset, 8, val);
1492 /* TODO: aggregate size */
1493 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1494 tvb_get_letohl(tvb, offset);
1495 proto_tree_add_uint64(tree, hf_pvfs_aggregate_size, tvb, offset, 8, val);
1498 /* num_contig_chunks */
1499 proto_tree_add_uint(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4,
1500 tvb_get_letohl(tvb, offset));
1504 proto_tree_add_text(tree, tvb, offset, 4, "depth: %d",
1505 tvb_get_letohl(tvb, offset));
1508 /* num_nested_req */
1509 proto_tree_add_text(tree, tvb, offset, 4, "num_nested_req: %d",
1510 tvb_get_letohl(tvb, offset));
1514 proto_tree_add_text(tree, tvb, offset, 4, "committed: %d",
1515 tvb_get_letohl(tvb, offset));
1519 proto_tree_add_text(tree, tvb, offset, 4, "refcount: %d",
1520 tvb_get_letohl(tvb, offset));
1527 ereg = tvb_get_letohl(tvb, offset);
1528 proto_tree_add_int(tree, hf_pvfs_ereg, tvb, offset, 4, ereg);
1532 sreg = tvb_get_letohl(tvb, offset);
1533 proto_tree_add_int(tree, hf_pvfs_sreg, tvb, offset, 4, sreg);
1540 dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1546 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1549 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1551 /* skip4 as per source code */
1555 offset = dissect_pvfs_io_type(tvb, tree, offset);
1558 offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
1561 proto_tree_add_uint(tree, hf_pvfs_server_nr, tvb, offset, 4,
1562 tvb_get_letohl(tvb, offset));
1566 proto_tree_add_uint(tree, hf_pvfs_server_count, tvb, offset, 4,
1567 tvb_get_letohl(tvb, offset));
1571 offset = dissect_pvfs_distribution(tvb, tree, offset);
1573 proto_tree_add_text(tree, tvb, offset, 4, "numreq: %d",
1574 tvb_get_letohl(tvb, offset));
1580 offset = dissect_pvfs_pint_request(tvb, tree, offset);
1582 /* TODO: remove this!!! */
1583 offset = tvb_length(tvb) - 16;
1586 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1587 tvb_get_letohl(tvb, offset);
1588 proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
1592 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1593 tvb_get_letohl(tvb, offset);
1594 proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
1601 dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1605 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1608 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1611 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1617 dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1621 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1623 /* parent_ref: fs_id */
1624 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1628 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1633 /* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
1635 dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
1636 int offset, packet_info *pinfo)
1639 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1642 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1646 /* starting_handle */
1647 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1649 /* attribute mask */
1650 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1656 dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1660 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1662 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
1665 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1668 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1673 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1674 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1677 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1678 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1681 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1682 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1687 /* TODO: incomplete */
1689 dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1693 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1696 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1699 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1704 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1705 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1708 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1709 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1712 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1713 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1719 dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1723 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1725 /* New directory entry handle */
1726 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
1730 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1733 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1736 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
1737 hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
1740 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
1741 hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
1744 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
1745 hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
1751 dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1757 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1760 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1765 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
1766 tvb_get_letohl(tvb, offset);
1767 proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
1771 proto_tree_add_text(tree, tvb, offset, 4, "flags: %u",
1772 tvb_get_letohl(tvb, offset));
1779 dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1785 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1790 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1792 /* handle_extent_array */
1793 count = tvb_get_letohl(tvb, offset);
1796 for (i = 0; i < count; i++)
1797 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1803 dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1806 /* object_ref: handle */
1807 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1809 /* object_ref: fs_id */
1810 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1813 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
1814 tvb_get_letohl(tvb, offset));
1818 proto_tree_add_text(tree, tvb, offset, 4, "dirent_limit: %d",
1819 tvb_get_letohl(tvb, offset));
1826 dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
1827 int offset, packet_info *pinfo)
1830 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1833 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1836 proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
1837 tvb_get_letohl(tvb, offset));
1844 dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
1845 int offset, packet_info *pinfo)
1848 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1851 offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
1857 dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1858 packet_info *pinfo _U_)
1861 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1867 dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
1868 int offset, packet_info *pinfo _U_)
1871 proto_tree_add_text(tree, tvb, offset, 4, "next_id: %d",
1872 tvb_get_letohl(tvb, offset));
1876 proto_tree_add_text(tree, tvb, offset, 4, "count: %d",
1877 tvb_get_letohl(tvb, offset));
1884 dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
1885 int offset, packet_info *pinfo)
1888 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1891 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1897 dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
1898 proto_tree *tree, int offset, packet_info *pinfo)
1900 guint32 handle_count, i;
1903 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1906 handle_count = tvb_get_letohl(tvb, offset);
1909 for (i = 0; i < handle_count; i++)
1912 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1919 dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
1920 int offset, packet_info *pinfo _U_)
1923 proto_tree_add_text(tree, tvb, offset, 4, "Event count: %d",
1924 tvb_get_letohl(tvb, offset));
1931 dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
1932 int offset, packet_info *pinfo)
1935 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1938 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1944 dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
1945 proto_tree *tree, int offset, packet_info *pinfo)
1948 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1951 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1957 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
1963 dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
1964 proto_tree *tree, int offset, packet_info *pinfo)
1967 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1970 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1975 /* TODO: untested/incomplete */
1977 dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset)
1980 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
1983 /* attribute value */
1984 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
1990 /* TODO: incomplete/untested */
1992 dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset)
1996 /* number of keys and vals */
1997 nKey = tvb_get_letohl(tvb, offset);
2000 for (i = 0; i < nKey; i++)
2001 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
2006 /* TODO: incomplete/untested */
2008 dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
2009 int offset, packet_info *pinfo)
2012 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2015 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2019 offset = dissect_ds_keyval_array(tvb, tree, offset);
2024 /* TODO: incomplete/untested */
2026 dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
2027 int offset, packet_info *pinfo)
2030 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2033 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2037 offset = dissect_ds_keyval_array(tvb, tree, offset);
2042 /* TODO: untested */
2044 dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
2045 int offset, packet_info *pinfo)
2048 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2051 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2054 offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
2060 dissect_pvfs2_release_number(tvbuff_t *tvb, proto_tree *tree, int offset)
2062 guint32 release_nr = tvb_get_letohl(tvb, offset);
2064 proto_tree_add_text(tree, tvb, offset, 4,
2065 "PVFS2 Release Number: %d (%d.%d.%d)",
2068 (release_nr % 10000) / 100,
2069 (release_nr % 10000) % 100);
2076 dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
2078 /* PVFS release number */
2079 offset = dissect_pvfs2_release_number(tvb, tree, offset);
2081 /* wire encoding type */
2082 proto_tree_add_uint(tree, hf_pvfs_encoding, tvb, offset,
2083 4, tvb_get_letohl(tvb, offset));
2087 proto_tree_add_uint(tree, hf_pvfs_server_op, tvb, offset, 4,
2088 tvb_get_letohl(tvb, offset));
2095 dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
2096 packet_info *pinfo, guint32 server_op)
2099 proto_tree_add_uint(tree, hf_pvfs_context_id, tvb, offset,
2100 4, tvb_get_letohl(tvb, offset));
2104 offset = dissect_pvfs_credentials(tvb, tree, offset);
2108 case PVFS_SERV_CREATE:
2109 offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
2112 case PVFS_SERV_REMOVE:
2113 offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
2117 offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
2120 case PVFS_SERV_GETATTR:
2121 offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
2124 case PVFS_SERV_SETATTR:
2125 offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
2128 case PVFS_SERV_LOOKUP_PATH:
2129 offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
2132 case PVFS_SERV_CRDIRENT:
2133 offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
2136 case PVFS_SERV_RMDIRENT:
2137 offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
2140 case PVFS_SERV_CHDIRENT:
2141 offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
2144 case PVFS_SERV_TRUNCATE:
2145 offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
2148 case PVFS_SERV_MKDIR:
2149 offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
2152 case PVFS_SERV_READDIR:
2153 offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
2157 case PVFS_SERV_GETCONFIG:
2158 /* No parameters in request */
2163 case PVFS_SERV_WRITE_COMPLETION:
2164 /* No parameters in request */
2168 case PVFS_SERV_FLUSH:
2169 offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
2172 case PVFS_SERV_MGMT_SETPARAM:
2173 offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
2178 case PVFS_SERV_MGMT_NOOP:
2179 /* No parameters in request */
2183 case PVFS_SERV_STATFS:
2184 offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
2188 case PVFS_SERV_PERF_UPDATE:
2189 /* No parameters in request */
2193 case PVFS_SERV_MGMT_PERF_MON:
2194 offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
2198 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2199 offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
2203 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2204 offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
2208 case PVFS_SERV_MGMT_EVENT_MON:
2209 offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
2213 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2214 offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
2218 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2219 offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
2223 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2224 offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
2229 case PVFS_SERV_JOB_TIMER:
2230 /* No parameters in request */
2234 case PVFS_SERV_PROTO_ERROR:
2235 /* TODO: is this necessary? */
2238 case PVFS_SERV_GETEATTR:
2239 offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
2242 case PVFS_SERV_SETEATTR:
2243 offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
2246 case PVFS_SERV_DELEATTR:
2247 offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
2251 /* TODO: what should we do here? */
2259 * =======================================================================
2261 * =======================================================================
2265 dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2269 return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2273 dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2275 return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
2279 dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
2280 int offset, packet_info *pinfo)
2282 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
2288 dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
2289 int offset, packet_info *pinfo)
2292 guint32 handle_count = 0;
2293 guint32 attr_count = 0;
2294 proto_item *attr_item = NULL;
2295 proto_tree *attr_tree = NULL;
2300 handle_count = tvb_get_letohl(tvb, offset);
2301 proto_tree_add_text(tree, tvb, offset, 4, "Handle Count: %d",
2305 /* TODO: add bounds checking */
2306 for (nCount = 0; nCount < handle_count; nCount++)
2307 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2311 /* array of attributes */
2312 attr_count = tvb_get_letohl(tvb, offset);
2316 attr_item = proto_tree_add_text(tree, tvb, offset, 4,
2317 "Attribute array (total items: %d)", attr_count);
2320 attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr);
2325 /* Array of attributes */
2326 for (nCount = 0; nCount < attr_count; nCount++)
2327 offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
2333 dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2337 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2343 dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2347 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2353 dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2357 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2363 dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2367 guint32 dirent_count = 0;
2371 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
2372 tvb_get_letohl(tvb, offset));
2377 /* directory_version */
2378 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
2379 tvb_get_letohl(tvb, offset);
2380 proto_tree_add_uint64(tree, hf_pvfs_directory_version, tvb, offset, 8,
2387 dirent_count = tvb_get_letohl(tvb, offset);
2388 proto_tree_add_text(tree, tvb, offset, 4, "dirent_count: %d",
2392 for (nCount = 0; nCount < dirent_count; nCount++)
2394 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
2395 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2402 * TODO: this code needs work! Not finished yet!
2405 dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
2409 guint32 total_bytes = 0, total_config_bytes = 0, total_lines = 0;
2410 guint32 bytes_processed = 0;
2411 guint32 length_remaining = 0;
2413 proto_item *item = NULL, *config_item = NULL;
2414 proto_tree *tree = NULL, *config_tree = NULL;
2415 /*guint8 truncated = 0;*/
2419 item = proto_tree_add_text(parent_tree, tvb, offset, 12,
2423 tree = proto_item_add_subtree(item, ett_pvfs_server_config);
2426 /* Total number of bytes in server config (incl. entry count) */
2427 total_bytes = tvb_get_letohl(tvb, offset);
2428 proto_tree_add_text(tree, tvb, offset, 4, "Total Bytes: %d",
2432 /* There must be at least 4 bytes of data returned to determine the
2433 * size of the server config data
2435 if (total_bytes < 4)
2437 /* Server config not returned, bail out */
2441 /* Number of entries in server config */
2442 total_lines = tvb_get_letohl(tvb, offset);
2443 proto_tree_add_text(tree, tvb, offset, 4, "Lines: %d", total_lines);
2446 /* Number of bytes in server config */
2447 total_config_bytes = tvb_get_letohl(tvb, offset);
2448 proto_tree_add_text(tree, tvb, offset, 4, "Config Bytes: %d",
2449 total_config_bytes);
2452 /* Get pointer to server config data */
2453 ptr = (char *) tvb_get_ptr(tvb, offset, total_config_bytes);
2455 /* Check if all data is available */
2456 length_remaining = tvb_length_remaining(tvb, offset);
2458 if (length_remaining < total_config_bytes)
2460 total_config_bytes = length_remaining;
2465 bytes_processed = 0;
2467 for (i = 0; i < total_lines; i++)
2469 guint8 entry[256], *pentry = entry, *tmp_entry = NULL;
2470 guint32 entry_length = 0, tmp_entry_length = 0;
2471 guint32 bufsiz = sizeof(entry);
2473 while ((*ptr != '\n') && (*ptr != '\0') &&
2474 (bytes_processed < total_config_bytes) &&
2475 (entry_length < bufsiz))
2483 if ((entry_length == bufsiz) &&
2484 ((entry[entry_length - 1] != '\n') &&
2485 (entry[entry_length - 1] != '\0')))
2488 * Single line of config data doesn't fit into provided buffer,
2489 * config data is malformed.
2495 if (bytes_processed == total_config_bytes)
2497 /* Oops... ran out of data before we could complete the entry */
2504 tmp_entry_length = entry_length;
2506 /* Remove all whitespace from front of entry */
2507 while ((tmp_entry_length > 0) && (!isalnum(*tmp_entry)) &&
2508 (*tmp_entry != '<'))
2514 if (tmp_entry[0] == '<')
2516 if (tmp_entry[tmp_entry_length - 1] == '>')
2519 if (tmp_entry[1] != '/')
2521 /* Opening token, create new tree root */
2522 config_item = proto_tree_add_text(tree, tvb, offset,
2523 tmp_entry_length, "%s", tmp_entry);
2526 config_tree = proto_item_add_subtree(config_item,
2527 ett_pvfs_server_config_branch);
2538 /* Malformed token */
2544 /* Insert items into the root config tree if there's no subtree
2547 if (config_tree == NULL)
2550 if (tmp_entry_length > 0)
2552 proto_tree_add_text(config_tree, tvb, offset, tmp_entry_length,
2557 offset += entry_length + 1;
2563 if (bytes_processed < total_config_bytes)
2565 /* We ran out of server config data */
2566 proto_tree_add_text(config_tree, tvb, offset, -1,
2567 "<MALFORMED OR TRUNCATED DATA>");
2574 dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
2578 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
2585 dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
2591 val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
2592 tvb_get_letohl(tvb, offset);
2594 proto_tree_add_uint64(tree, hf_pvfs_prev_value, tvb, offset, 8, val);
2602 dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2607 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2609 /* bytes_available */
2610 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
2614 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
2617 /* RAM bytes total */
2618 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
2621 /* RAM bytes free */
2622 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
2625 /* load average (1s) */
2626 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
2629 /* load average (5s) */
2630 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
2633 /* load average (15s) */
2634 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
2637 /* uptime (seconds) */
2638 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
2641 /* handles_available_count */
2642 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
2645 /* handles_total_count */
2646 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
2653 dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
2656 proto_item *stat_item = NULL;
2657 proto_tree *stat_tree = NULL;
2661 stat_item = proto_tree_add_text(tree, tvb, offset, 48,
2662 "Stat Array - Element %d", nItem);
2665 stat_tree = proto_item_add_subtree(stat_item,
2666 ett_pvfs_mgmt_perf_stat);
2669 /* TODO: valid_flag */
2670 proto_tree_add_text(stat_tree, tvb, offset, 4, "valid_flag: %d",
2671 tvb_get_letohl(tvb, offset));
2675 proto_tree_add_text(stat_tree, tvb, offset, 4, "id: %d",
2676 tvb_get_letohl(tvb, offset));
2679 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
2681 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
2683 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
2685 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
2687 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
2694 dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
2697 guint32 perf_array_count, i;
2699 /* TODO: suggested_next_id */
2700 proto_tree_add_text(tree, tvb, offset, 4, "suggested_next_id: %d",
2701 tvb_get_letohl(tvb, offset));
2706 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms,
2708 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms,
2713 /* TODO: perf_array_count */
2714 perf_array_count = tvb_get_letohl(tvb, offset);
2715 proto_tree_add_text(tree, tvb, offset, 4, "perf_array_count: %d",
2719 for (i = 0; i < perf_array_count; i++)
2720 offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
2726 dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
2727 int offset, packet_info *pinfo)
2729 guint32 handle_count, i;
2732 proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
2733 tvb_get_letohl(tvb, offset));
2737 handle_count = tvb_get_letohl(tvb, offset);
2738 proto_tree_add_text(tree, tvb, offset, 4, "handle_count: %d",
2742 /* TODO: this could be improved */
2743 for (i = 0; i < handle_count; i++)
2744 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2750 dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
2753 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2754 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2755 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
2756 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
2758 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
2760 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2766 dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
2767 int offset, packet_info *pinfo)
2769 guint32 dspace_info_count, i;
2770 proto_item *arr_item = NULL;
2771 proto_tree *arr_tree = NULL;
2775 /* dspace_info_count */
2776 dspace_info_count = tvb_get_letohl(tvb, offset);
2777 proto_tree_add_text(tree, tvb, offset, 4, "dspace_info_count: %d",
2780 if ((dspace_info_count > 0) && (tree))
2782 arr_item = proto_tree_add_text(tree, tvb, offset,
2783 dspace_info_count * 40, "dspace_info Array (%d items)",
2787 arr_tree = proto_item_add_subtree(arr_item,
2788 ett_pvfs_mgmt_dspace_info);
2791 for (i = 0; i < dspace_info_count; i++)
2792 offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
2798 dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
2802 proto_tree_add_text(tree, tvb, offset, 4, "api: %d",
2803 tvb_get_letohl(tvb, offset));
2807 proto_tree_add_text(tree, tvb, offset, 4, "operation: %d",
2808 tvb_get_letohl(tvb, offset));
2812 proto_tree_add_text(tree, tvb, offset, 4, "value: %d",
2813 tvb_get_letohl(tvb, offset));
2817 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
2821 proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
2822 tvb_get_letohl(tvb, offset));
2826 proto_tree_add_text(tree, tvb, offset, 4, "tv_sec: %d",
2827 tvb_get_letohl(tvb, offset));
2831 proto_tree_add_text(tree, tvb, offset, 4, "tv_usec: %d",
2832 tvb_get_letohl(tvb, offset));
2841 dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
2842 int offset, packet_info *pinfo)
2845 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2848 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2854 dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
2855 proto_tree *tree, int offset, packet_info *pinfo)
2858 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2863 /* TODO: untested */
2865 dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2866 packet_info *pinfo _U_)
2870 /* Dissect nKey & ds_keyval array */
2871 offset = dissect_ds_keyval_array(tvb, tree, offset);
2877 dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2878 packet_info *pinfo, guint32 server_op)
2881 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2885 case PVFS_SERV_CREATE:
2886 offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
2890 case PVFS_SERV_REMOVE:
2891 /* No result data */
2896 offset = dissect_pvfs2_io_response(tvb, tree, offset);
2899 case PVFS_SERV_GETATTR:
2900 offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
2903 case PVFS_SERV_SETATTR:
2904 /* No result data */
2907 case PVFS_SERV_LOOKUP_PATH:
2908 offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
2912 case PVFS_SERV_CRDIRENT:
2913 /* No result data */
2917 case PVFS_SERV_RMDIRENT:
2918 offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
2921 case PVFS_SERV_CHDIRENT:
2922 offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
2926 case PVFS_SERV_TRUNCATE:
2927 /* No result data */
2931 case PVFS_SERV_MKDIR:
2932 offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
2935 case PVFS_SERV_READDIR:
2936 offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
2939 case PVFS_SERV_GETCONFIG:
2940 offset = dissect_pvfs2_getconfig_response(tvb, tree, offset);
2943 case PVFS_SERV_WRITE_COMPLETION:
2944 offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
2948 case PVFS_SERV_FLUSH:
2949 /* No result data */
2953 case PVFS_SERV_MGMT_SETPARAM:
2954 offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
2958 case PVFS_SERV_MGMT_NOOP:
2959 /* No result data */
2963 case PVFS_SERV_STATFS:
2964 offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
2968 case PVFS_SERV_PERF_UPDATE:
2969 /* No result data */
2973 case PVFS_SERV_MGMT_PERF_MON:
2974 offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
2977 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2978 offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
2982 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2983 offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
2987 case PVFS_SERV_MGMT_EVENT_MON:
2988 offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
2991 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2992 offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
2997 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2998 /* No result data */
3002 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
3003 offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
3008 case PVFS_SERV_JOB_TIMER:
3009 /* No result data */
3013 case PVFS_SERV_PROTO_ERROR:
3014 /* No result data */
3017 /* TODO: untested */
3018 case PVFS_SERV_GETEATTR:
3019 offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
3023 case PVFS_SERV_SETEATTR:
3024 /* No result data */
3029 case PVFS_SERV_DELEATTR:
3030 /* No result data */
3035 /* TODO: what do we do here? */
3042 static GHashTable *pvfs2_io_tracking_value_table = NULL;
3044 typedef struct pvfs2_io_tracking_key
3047 } pvfs2_io_tracking_key_t;
3049 typedef struct pvfs2_io_tracking_value
3051 guint32 request_frame_num;
3052 guint32 response_frame_num;
3053 guint32 flow_frame_num;
3055 } pvfs2_io_tracking_value_t;
3058 pvfs2_io_tracking_equal(gconstpointer k1, gconstpointer k2)
3060 const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
3061 const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
3063 return (key1->tag == key2->tag);
3067 pvfs2_io_tracking_hash(gconstpointer k)
3069 const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
3071 return (guint) ((key->tag >> 32) ^ ((guint32) key->tag));
3075 pvfs2_io_tracking_init(void)
3077 if (pvfs2_io_tracking_value_table != NULL)
3078 g_hash_table_destroy(pvfs2_io_tracking_value_table);
3080 pvfs2_io_tracking_value_table = g_hash_table_new(pvfs2_io_tracking_hash,
3081 pvfs2_io_tracking_equal);
3084 static pvfs2_io_tracking_value_t *
3085 pvfs2_io_tracking_new_with_tag(guint64 tag, guint32 num)
3087 pvfs2_io_tracking_value_t *value;
3088 pvfs2_io_tracking_key_t *newkey;
3090 newkey = (pvfs2_io_tracking_key_t *) se_alloc0(sizeof(*newkey));
3093 value = se_alloc0(sizeof(*value));
3095 g_hash_table_insert(pvfs2_io_tracking_value_table, newkey, value);
3097 value->request_frame_num = num;
3103 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
3104 gboolean dissect_other_as_continuation _U_)
3107 proto_item *item = NULL, *hitem = NULL;
3108 proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
3112 pvfs2_io_tracking_value_t *val = NULL;
3114 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
3116 col_clear(pinfo->cinfo, COL_INFO);
3120 item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, ENC_NA);
3123 pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
3126 proto_tree_add_text(pvfs_tree, tvb, 0, -1, "Version: 2");
3128 /* PVFS packet header is 24 bytes */
3129 hitem = proto_tree_add_text(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
3132 pvfs_htree = proto_item_add_subtree(hitem, ett_pvfs_hdr);
3135 proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3138 /* TCP message mode (32-bit) */
3139 mode = tvb_get_letohl(tvb, offset);
3140 proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
3144 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
3147 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
3149 /* Lookahead to get server_op (invalid if frame contains flow data) */
3150 server_op = tvb_get_letohl(tvb, offset + 8);
3152 if (mode == TCP_MODE_UNEXP)
3154 /* Add entry to tracking table for PVFS_SERV_IO request */
3155 if ((server_op == PVFS_SERV_IO) && !pinfo->fd->flags.visited)
3156 val = pvfs2_io_tracking_new_with_tag(tag, pinfo->fd->num);
3160 pvfs2_io_tracking_key_t key;
3162 memset(&key, 0, sizeof(key));
3165 val = g_hash_table_lookup(pvfs2_io_tracking_value_table, &key);
3167 /* If this frame contains a known PVFS_SERV_IO tag, track it */
3168 if (val && !pinfo->fd->flags.visited)
3170 /* If response HAS NOT been seen, mark this frame as response */
3171 if (val->response_frame_num == 0)
3172 val->response_frame_num = pinfo->fd->num;
3175 /* If response HAS been seen, this frame is flow data */
3176 if (val->flow_frame_num == 0)
3177 val->flow_frame_num = pinfo->fd->num;
3182 if (val && (val->flow_frame_num == pinfo->fd->num))
3184 /* This frame is marked as being flow data */
3185 col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
3187 proto_tree_add_text(pvfs_tree, tvb, offset, -1, "<data>");
3192 /* Extract common part of packet found in requests and responses */
3193 offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
3195 /* Update column info display */
3196 if (check_col(pinfo->cinfo, COL_INFO))
3198 col_add_str(pinfo->cinfo, COL_INFO,
3199 val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
3201 col_append_str(pinfo->cinfo, COL_INFO,
3202 (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
3205 /* TODO: handle all modes */
3206 if (mode == TCP_MODE_UNEXP)
3209 offset = dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
3213 /* TODO: re-examine this! */
3215 if (mode == TCP_MODE_REND)
3218 * TODO: move this code outside so it's common for requests and
3222 col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
3228 offset = dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
3236 /* Register the protocol with Wireshark */
3238 proto_register_pvfs(void)
3240 static hf_register_info hf[] = {
3241 { &hf_pvfs_magic_nr,
3242 { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
3243 NULL, 0, NULL, HFILL }},
3246 { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
3247 VALS(names_pvfs_mode), 0, NULL, HFILL }},
3250 { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
3251 NULL, 0, NULL, HFILL }},
3254 { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
3255 NULL, 0, NULL, HFILL }},
3257 { &hf_pvfs_release_number,
3258 { "Release Number", "pvfs.release_number", FT_UINT32, BASE_DEC,
3259 NULL, 0, NULL, HFILL }},
3261 { &hf_pvfs_encoding,
3262 { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
3263 VALS(names_pvfs_encoding), 0, NULL, HFILL }},
3265 { &hf_pvfs_server_op,
3266 { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
3267 VALS(names_pvfs_server_op), 0, NULL, HFILL }},
3270 { "Handle", "pvfs.handle", FT_BYTES, BASE_NONE,
3271 NULL, 0, NULL, HFILL }},
3274 { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
3275 NULL, 0, "File System ID", HFILL }},
3277 { &hf_pvfs_attrmask,
3278 { "attrmask", "pvfs.attrmask", FT_UINT32, BASE_HEX,
3279 NULL, 0, "Attribute Mask", HFILL }},
3282 { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
3283 VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
3286 { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
3287 VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
3290 { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
3291 VALS(names_pvfs_error), 0, NULL, HFILL }},
3294 { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3295 NULL, 0, "Access Time", HFILL }},
3297 { &hf_pvfs_atime_sec,
3298 { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
3299 NULL, 0, "Access Time (seconds)", HFILL }},
3301 { &hf_pvfs_atime_nsec,
3302 { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
3303 NULL, 0, "Access Time (microseconds)", HFILL }},
3306 { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3307 NULL, 0, "Modify Time", HFILL }},
3309 { &hf_pvfs_mtime_sec,
3310 { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
3311 NULL, 0, "Modify Time (seconds)", HFILL }},
3313 { &hf_pvfs_mtime_nsec,
3314 { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
3315 NULL, 0, "Modify Time (microseconds)", HFILL }},
3318 { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3319 NULL, 0, "Creation Time", HFILL }},
3321 { &hf_pvfs_ctime_sec,
3322 { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
3323 NULL, 0, "Creation Time (seconds)", HFILL }},
3325 { &hf_pvfs_ctime_nsec,
3326 { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
3327 NULL, 0, "Creation Time (microseconds)", HFILL }},
3329 { &hf_pvfs_parent_atime,
3330 { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3331 NULL, 0, "Access Time", HFILL }},
3333 { &hf_pvfs_parent_atime_sec,
3334 { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
3335 NULL, 0, "Access Time (seconds)", HFILL }},
3337 { &hf_pvfs_parent_atime_nsec,
3338 { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
3339 NULL, 0, "Access Time (microseconds)", HFILL }},
3341 { &hf_pvfs_parent_mtime,
3342 { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3343 NULL, 0, "Modify Time", HFILL }},
3345 { &hf_pvfs_parent_mtime_sec,
3346 { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
3347 NULL, 0, "Modify Time (seconds)", HFILL }},
3349 { &hf_pvfs_parent_mtime_nsec,
3350 { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
3351 NULL, 0, "Modify Time (microseconds)", HFILL }},
3353 { &hf_pvfs_parent_ctime,
3354 { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3355 NULL, 0, "Creation Time", HFILL }},
3357 { &hf_pvfs_parent_ctime_sec,
3358 { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
3359 NULL, 0, "Creation Time (seconds)", HFILL }},
3361 { &hf_pvfs_parent_ctime_nsec,
3362 { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
3363 NULL, 0, "Creation Time (microseconds)", HFILL }},
3365 { &hf_pvfs_dirent_count,
3366 { "Dir Entry Count", "pvfs.dirent_count", FT_UINT64, BASE_DEC,
3367 NULL, 0, "Directory Entry Count", HFILL }},
3369 { &hf_pvfs_directory_version,
3370 { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
3371 NULL, 0, NULL, HFILL }},
3374 { "Path", "pvfs.path", FT_STRING, BASE_NONE,
3375 NULL, 0, NULL, HFILL }},
3377 { &hf_pvfs_total_completed,
3378 { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
3379 NULL, 0, NULL, HFILL }},
3382 { "Name", "pvfs.distribution.name", FT_STRING, BASE_NONE,
3383 NULL, 0, "Distribution Name", HFILL }},
3385 { &hf_pvfs_aggregate_size,
3386 { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
3387 NULL, 0, NULL, HFILL }},
3390 { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
3391 VALS(names_pvfs_io_type), 0, NULL, HFILL }},
3393 { &hf_pvfs_flowproto_type,
3394 { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
3395 VALS(names_pvfs_flowproto_type), 0, NULL, HFILL }},
3397 { &hf_pvfs_server_param,
3398 { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
3399 VALS(names_pvfs_server_param), 0, NULL, HFILL }},
3401 { &hf_pvfs_prev_value,
3402 { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
3403 NULL, 0, NULL, HFILL }},
3405 { &hf_pvfs_ram_free_bytes,
3406 { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
3407 NULL, 0, NULL, HFILL }},
3409 { &hf_pvfs_bytes_available,
3410 { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
3411 NULL, 0, NULL, HFILL }},
3413 { &hf_pvfs_bytes_total,
3414 { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
3415 NULL, 0, NULL, HFILL }},
3417 { &hf_pvfs_ram_bytes_total,
3418 { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
3419 NULL, 0, NULL, HFILL }},
3421 { &hf_pvfs_ram_bytes_free,
3422 { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
3423 NULL, 0, NULL, HFILL }},
3425 { &hf_pvfs_load_average_1s,
3426 { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
3427 NULL, 0, NULL, HFILL }},
3429 { &hf_pvfs_load_average_5s,
3430 { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
3431 NULL, 0, NULL, HFILL }},
3433 { &hf_pvfs_load_average_15s,
3434 { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
3435 NULL, 0, NULL, HFILL }},
3437 { &hf_pvfs_uptime_seconds,
3438 { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
3439 NULL, 0, NULL, HFILL }},
3441 { &hf_pvfs_handles_available,
3442 { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
3443 NULL, 0, NULL, HFILL }},
3445 { &hf_pvfs_handles_total,
3446 { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
3447 NULL, 0, NULL, HFILL }},
3450 * This is used when the field returns 64-bits but we're only interested
3451 * in the lower 32-bit bits.
3454 { "Unused", "pvfs.unused", FT_UINT32, BASE_DEC,
3455 NULL, 0, NULL, HFILL }},
3457 { &hf_pvfs_context_id,
3458 { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
3459 NULL, 0, NULL, HFILL }},
3462 { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
3463 NULL, 0, NULL, HFILL }},
3466 { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
3467 NULL, 0, NULL, HFILL }},
3470 { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
3471 NULL, 0, NULL, HFILL }},
3474 { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
3475 NULL, 0, NULL, HFILL }},
3477 { &hf_pvfs_end_time_ms,
3478 { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
3479 NULL, 0, NULL, HFILL }},
3481 { &hf_pvfs_cur_time_ms,
3482 { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
3483 NULL, 0, NULL, HFILL }},
3485 { &hf_pvfs_start_time_ms,
3486 { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
3487 NULL, 0, NULL, HFILL }},
3489 { &hf_pvfs_bytes_written,
3490 { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
3491 NULL, 0, NULL, HFILL }},
3493 { &hf_pvfs_bytes_read,
3494 { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
3495 NULL, 0, NULL, HFILL }},
3497 { &hf_pvfs_metadata_write,
3498 { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
3499 NULL, 0, NULL, HFILL }},
3501 { &hf_pvfs_metadata_read,
3502 { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
3503 NULL, 0, NULL, HFILL }},
3506 { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
3507 BASE_DEC, NULL, 0, "Size of bstream", HFILL }},
3510 { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
3511 BASE_DEC, NULL, 0, "Number of keyvals", HFILL }},
3513 { &hf_pvfs_id_gen_t,
3514 { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
3515 NULL, 0, NULL, HFILL }},
3517 { &hf_pvfs_attribute_key,
3518 { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_NONE,
3519 NULL, 0, NULL, HFILL }},
3521 { &hf_pvfs_attribute_value,
3522 { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_NONE,
3523 NULL, 0, NULL, HFILL }},
3525 { &hf_pvfs_strip_size,
3526 { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
3527 NULL, 0, "Strip size (bytes)", HFILL }},
3529 /* TODO: need description */
3531 { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
3532 NULL, 0, NULL, HFILL }},
3534 /* TODO: need description */
3536 { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
3537 NULL, 0, NULL, HFILL }},
3539 { &hf_pvfs_num_eregs,
3540 { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
3541 NULL, 0, NULL, HFILL }},
3543 { &hf_pvfs_num_blocks,
3544 { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
3545 NULL, 0, NULL, HFILL }},
3547 { &hf_pvfs_num_contig_chunks,
3548 { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
3549 BASE_DEC, NULL, 0, NULL, HFILL }},
3551 { &hf_pvfs_server_nr,
3552 { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
3553 NULL, 0, NULL, HFILL }},
3555 { &hf_pvfs_server_count,
3556 { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
3557 NULL, 0, NULL, HFILL }},
3559 { &hf_pvfs_fh_length,
3560 { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
3561 NULL, 0, "file handle length", HFILL }},
3564 { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
3565 NULL, 0, "file handle hash", HFILL }},
3568 /* Setup protocol subtree array */
3569 static gint *ett[] = {
3572 &ett_pvfs_credentials,
3573 &ett_pvfs_server_config,
3574 &ett_pvfs_server_config_branch,
3577 &ett_pvfs_extent_array_tree,
3578 &ett_pvfs_extent_item,
3580 &ett_pvfs_attr_tree,
3581 &ett_pvfs_distribution,
3582 &ett_pvfs_mgmt_perf_stat,
3583 &ett_pvfs_mgmt_dspace_info,
3587 module_t *pvfs_module;
3589 /* Register the protocol name and description */
3590 proto_pvfs = proto_register_protocol("Parallel Virtual File System",
3594 * Required function calls to register the header fields and
3598 proto_register_field_array(proto_pvfs, hf, array_length(hf));
3599 proto_register_subtree_array(ett, array_length(ett));
3601 register_init_routine(pvfs2_io_tracking_init);
3603 pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
3604 prefs_register_bool_preference(pvfs_module, "desegment",
3605 "Reassemble PVFS messages spanning multiple TCP segments",
3606 "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
3607 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3612 proto_reg_handoff_pvfs(void)
3614 dissector_handle_t pvfs_handle;
3616 pvfs_handle = new_create_dissector_handle(dissect_pvfs_heur, proto_pvfs);
3617 dissector_add_uint("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
3619 heur_dissector_add("tcp", dissect_pvfs_heur, proto_pvfs);