aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2005-12-07 09:51:31 +0000
committerGuy Harris <guy@alum.mit.edu>2005-12-07 09:51:31 +0000
commite4106ae5f806e58e51e365bbc077dd748657fc70 (patch)
tree3d99d32909a08685707240376e0e044960c98369 /epan
parent6afd45377d8fdd17a0b19dae45f658fe993ae9de (diff)
Fix oroperties, get rid of CRs.
svn path=/trunk/; revision=16719
Diffstat (limited to 'epan')
-rw-r--r--[-rwxr-xr-x]epan/dissectors/packet-pvfs2.c7260
1 files changed, 3630 insertions, 3630 deletions
diff --git a/epan/dissectors/packet-pvfs2.c b/epan/dissectors/packet-pvfs2.c
index dea34011e1..5f858c4f21 100755..100644
--- a/epan/dissectors/packet-pvfs2.c
+++ b/epan/dissectors/packet-pvfs2.c
@@ -1,3630 +1,3630 @@
-/* packet-pvfs.c
- * Routines for pvfs2 packet dissection
- * By Mike Frisch <mfrisch@platform.com>
- * Joint and Several Copyright 2005, Mike Frisch and Platform Computing Inc.
- *
- * $Id: packet-pvfs.c,v 1.32 2005/10/05 21:13:30 mfrisch Exp $
- *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
- * Copyright 1998 Gerald Combs
- *
- * Copied from packet-smb.c and others
- *
- * TODO
- *
- * - Add filename snooping (match file handles with file names),
- * similar to how packet-rpc.c/packet-nfs.c implements it
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <glib.h>
-
-#include <epan/packet.h>
-#include <epan/prefs.h>
-#include <epan/emem.h>
-#include <epan/strutil.h>
-#include <epan/prefs.h>
-#include "packet-tcp.h"
-
-#define TCP_PORT_PVFS2 3334
-
-#define PVFS2_FH_LENGTH 8
-
-/* Header incl. magic number, mode, tag, size */
-#define BMI_HEADER_SIZE 24
-
-/* desegmentation of PVFS over TCP */
-static gboolean pvfs_desegment = TRUE;
-
-/* Forward declaration we need below */
-void proto_reg_handoff_pvfs(void);
-
-/* Initialize the protocol and registered fields */
-static int proto_pvfs = -1;
-static int hf_pvfs_magic_nr = -1;
-static int hf_pvfs_mode = -1;
-static int hf_pvfs_tag = -1;
-static int hf_pvfs_size = -1;
-static int hf_pvfs_release_number = -1;
-static int hf_pvfs_encoding = -1;
-static int hf_pvfs_server_op = -1;
-static int hf_pvfs_handle = -1;
-static int hf_pvfs_fs_id = -1;
-static int hf_pvfs_attrmask = -1;
-static int hf_pvfs_attr = -1;
-static int hf_pvfs_ds_type = -1;
-static int hf_pvfs_error = -1;
-static int hf_pvfs_atime = -1;
-static int hf_pvfs_atime_sec = -1;
-static int hf_pvfs_atime_nsec = -1;
-static int hf_pvfs_mtime = -1;
-static int hf_pvfs_mtime_sec = -1;
-static int hf_pvfs_mtime_nsec = -1;
-static int hf_pvfs_ctime = -1;
-static int hf_pvfs_ctime_sec = -1;
-static int hf_pvfs_ctime_nsec = -1;
-static int hf_pvfs_parent_atime = -1;
-static int hf_pvfs_parent_atime_sec = -1;
-static int hf_pvfs_parent_atime_nsec = -1;
-static int hf_pvfs_parent_mtime = -1;
-static int hf_pvfs_parent_mtime_sec = -1;
-static int hf_pvfs_parent_mtime_nsec = -1;
-static int hf_pvfs_parent_ctime = -1;
-static int hf_pvfs_parent_ctime_sec = -1;
-static int hf_pvfs_parent_ctime_nsec = -1;
-static int hf_pvfs_dirent_count = -1;
-static int hf_pvfs_directory_version = -1;
-static int hf_pvfs_path = -1;
-static int hf_pvfs_total_completed = -1;
-static int hf_pvfs_io_dist = -1;
-static int hf_pvfs_aggregate_size = -1;
-static int hf_pvfs_io_type = -1;
-static int hf_pvfs_flowproto_type = -1;
-static int hf_pvfs_server_param = -1;
-static int hf_pvfs_prev_value = -1;
-static int hf_pvfs_ram_free_bytes = -1;
-static int hf_pvfs_bytes_available = -1;
-static int hf_pvfs_bytes_total = -1;
-static int hf_pvfs_ram_bytes_total = -1;
-static int hf_pvfs_ram_bytes_free = -1;
-static int hf_pvfs_load_average_1s = -1;
-static int hf_pvfs_load_average_5s = -1;
-static int hf_pvfs_load_average_15s = -1;
-static int hf_pvfs_uptime_seconds = -1;
-static int hf_pvfs_handles_available = -1;
-static int hf_pvfs_handles_total = -1;
-static int hf_pvfs_unused = -1;
-static int hf_pvfs_context_id = -1;
-static int hf_pvfs_offset = -1;
-static int hf_pvfs_stride = -1;
-static int hf_pvfs_lb = -1;
-static int hf_pvfs_ub = -1;
-static int hf_pvfs_end_time_ms = -1;
-static int hf_pvfs_cur_time_ms = -1;
-static int hf_pvfs_start_time_ms = -1;
-static int hf_pvfs_bytes_written = -1;
-static int hf_pvfs_bytes_read = -1;
-static int hf_pvfs_metadata_write = -1;
-static int hf_pvfs_metadata_read = -1;
-static int hf_pvfs_b_size = -1;
-static int hf_pvfs_k_size = -1;
-static int hf_pvfs_id_gen_t = -1;
-static int hf_pvfs_attribute_key = -1;
-static int hf_pvfs_attribute_value = -1;
-static int hf_pvfs_strip_size = -1;
-static int hf_pvfs_ereg = -1;
-static int hf_pvfs_sreg = -1;
-static int hf_pvfs_num_eregs = -1;
-static int hf_pvfs_num_blocks = -1;
-static int hf_pvfs_num_contig_chunks = -1;
-static int hf_pvfs_server_nr = -1;
-static int hf_pvfs_server_count = -1;
-static int hf_pvfs_fh_length = -1;
-static int hf_pvfs_fh_hash = -1;
-
-/* Initialize the subtree pointers */
-static gint ett_pvfs = -1;
-static gint ett_pvfs_hdr = -1;
-static gint ett_pvfs_credentials = -1;
-static gint ett_pvfs_server_config = -1;
-static gint ett_pvfs_server_config_branch = -1;
-static gint ett_pvfs_attrmask = -1;
-static gint ett_pvfs_time = -1;
-static gint ett_pvfs_extent_array_tree = -1;
-static gint ett_pvfs_extent_item = -1;
-static gint ett_pvfs_string = -1;
-static gint ett_pvfs_attr_tree = -1;
-static gint ett_pvfs_distribution = -1;
-static gint ett_pvfs_mgmt_perf_stat = -1;
-static gint ett_pvfs_mgmt_dspace_info = -1;
-static gint ett_pvfs_attr = -1;
-static gint ett_pvfs_fh = -1;
-
-#define BMI_MAGIC_NR 51903
-
-static const value_string names_pvfs_mode[] =
-{
-#define TCP_MODE_IMMED 1
- { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
-#define TCP_MODE_UNEXP 2
- { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
-#define TCP_MODE_EAGER 4
- { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
-#define TCP_MODE_REND 8
- { TCP_MODE_REND, "TCP_MODE_REND" },
- { 0, NULL }
-};
-
-static const value_string names_pvfs_encoding[] =
-{
-#define PVFS_ENCODING_DIRECT 1
- { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
-#define PVFS_ENCODING_LE_BFIELD 2
- { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
-#define PVFS_ENCODING_XDR 3
- { PVFS_ENCODING_XDR, "ENCODING_XDR" },
- { 0, NULL }
-};
-
-static const value_string names_pvfs_io_type[] =
-{
-#define PVFS_IO_READ 1
- { PVFS_IO_READ, "PVFS_IO_READ" },
-#define PVFS_IO_WRITE 2
- { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
- { 0, NULL }
-};
-
-static const value_string names_pvfs_flowproto_type[] =
-{
-#define FLOWPROTO_DUMP_OFFSETS 1
- { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
-#define FLOWPROTO_BMI_CACHE 2
- { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
-#define FLOWPROTO_MULTIQUEUE 3
- { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
- { 0, NULL }
-};
-
-static const value_string names_pvfs_server_param[] =
-{
-#define PVFS_SERV_PARAM_INVALID 0
- { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
-#define PVFS_SERV_PARAM_GOSSIP_MASK 1
- { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
-#define PVFS_SERV_PARAM_FSID_CHECK 2
- { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
-#define PVFS_SERV_PARAM_ROOT_CHECK 3
- { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
-#define PVFS_SERV_PARAM_MODE 4
- { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
-#define PVFS_SERV_PARAM_EVENT_ON 5
- { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
-#define PVFS_SERV_PARAM_EVENT_MASKS 6
- { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
- { 0, NULL }
-};
-
-static const value_string names_pvfs_server_mode[] =
-{
-#define PVFS_SERVER_NORMAL_MODE 1
- { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
-#define PVFS_SERVER_ADMIN_MODE 2
- { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
- { 0, NULL }
-};
-
-/* Forward declaration */
-static gboolean
-dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- gboolean dissect_other_as_continuation);
-
-
-static void dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- dissect_pvfs_common(tvb, pinfo, tree, FALSE);
-
-}
-
-static guint get_pvfs_pdu_len(tvbuff_t *tvb, int offset)
-{
- guint32 plen;
-
- /*
- * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
- */
- plen = tvb_get_letohl(tvb, offset + 16);
-
- return plen+24;
-}
-
-static int
-dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- guint32 magic_nr, mode;
- guint64 size;
-
- /* verify that this is indeed PVFS and that it looks sane */
- if(tvb_length_remaining(tvb,0)<24){
- /* too few bytes remaining to verify the header */
- return 0;
- }
-
- /* validate the magic number */
- magic_nr = tvb_get_letohl(tvb, 0);
- if(magic_nr!=BMI_MAGIC_NR){
- return 0;
- }
-
- /* Validate the TCP message mode (32-bit) */
- mode = tvb_get_letohl(tvb, 4);
- switch(mode){
- case TCP_MODE_IMMED:
- case TCP_MODE_UNEXP:
- case TCP_MODE_EAGER:
- case TCP_MODE_REND:
- break;
- default:
- /* invalid mode, not a PVFS packet */
- return 0;
- }
-
- /* validate the size : assume size must be >0 and less than 1000000 */
- size=tvb_get_letohl(tvb, 20);
- size<<=32;
- size|=tvb_get_letohl(tvb, 16);
- if((size>1000000)||(size==0)){
- return 0;
- }
-
- tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
- dissect_pvfs_pdu);
-
- return tvb_length(tvb);
-}
-
-static const value_string names_pvfs_server_op[] =
-{
-#define PVFS_SERV_INVALID 0
- { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
-#define PVFS_SERV_CREATE 1
- { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
-#define PVFS_SERV_REMOVE 2
- { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
-#define PVFS_SERV_IO 3
- { PVFS_SERV_IO, "PVFS_SERV_IO" },
-#define PVFS_SERV_GETATTR 4
- { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
-#define PVFS_SERV_SETATTR 5
- { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
-#define PVFS_SERV_LOOKUP_PATH 6
- { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
-#define PVFS_SERV_CRDIRENT 7
- { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
-#define PVFS_SERV_RMDIRENT 8
- { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
-#define PVFS_SERV_CHDIRENT 9
- { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
-#define PVFS_SERV_TRUNCATE 10
- { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
-#define PVFS_SERV_MKDIR 11
- { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
-#define PVFS_SERV_READDIR 12
- { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
-#define PVFS_SERV_GETCONFIG 13
- { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
-#define PVFS_SERV_WRITE_COMPLETION 14
- { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
-#define PVFS_SERV_FLUSH 15
- { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
-#define PVFS_SERV_MGMT_SETPARAM 16
- { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
-#define PVFS_SERV_MGMT_NOOP 17
- { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
-#define PVFS_SERV_STATFS 18
- { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
-#define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
- { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
-#define PVFS_SERV_MGMT_PERF_MON 20
- { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
-#define PVFS_SERV_MGMT_ITERATE_HANDLES 21
- { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
-#define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
- { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
-#define PVFS_SERV_MGMT_EVENT_MON 23
- { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
-#define PVFS_SERV_MGMT_REMOVE_OBJECT 24
- { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
-#define PVFS_SERV_MGMT_REMOVE_DIRENT 25
- { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
-#define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
- { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
-#define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
- { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
-#define PVFS_SERV_PROTO_ERROR 28
- { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
-#define PVFS_SERV_GETEATTR 29
- { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
-#define PVFS_SERV_SETEATTR 30
- { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
-#define PVFS_SERV_DELEATTR 31
- { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
- { 0, NULL }
-};
-
-/* special bits used to differentiate PVFS error codes from system
- * * errno values
- * */
-#define PVFS_ERROR_BIT (1 << 30)
-
-/* a shorthand to make the error code definitions more readable */
-#define E(num) (num|PVFS_ERROR_BIT)
-
-static const value_string names_pvfs_error[] = {
- { 0, "Success" },
-#define PVFS_EPERM E(1) /* Operation not permitted */
- { PVFS_EPERM, "PVFS_EPERM" },
-#define PVFS_ENOENT E(2) /* No such file or directory */
- { PVFS_ENOENT, "PVFS_ENOENT" },
-#define PVFS_EINTR E(3) /* Interrupted system call */
- { PVFS_EINTR, "PVFS_EINTR" },
-#define PVFS_EIO E(4) /* I/O error */
- { PVFS_EIO, "PVFS_EIO" },
-#define PVFS_ENXIO E(5) /* No such device or address */
- { PVFS_ENXIO, "PVFS_ENXIO" },
-#define PVFS_EBADF E(6) /* Bad file number */
- { PVFS_EBADF, "PVFS_EBADF" },
-#define PVFS_EAGAIN E(7) /* Try again */
- { PVFS_EAGAIN, "PVFS_EAGAIN" },
-#define PVFS_ENOMEM E(8) /* Out of memory */
- { PVFS_ENOMEM, "PVFS_ENOMEM" },
-#define PVFS_EFAULT E(9) /* Bad address */
- { PVFS_EFAULT, "PVFS_EFAULT" },
-#define PVFS_EBUSY E(10) /* Device or resource busy */
- { PVFS_EBUSY, "PVFS_EBUSY" },
-#define PVFS_EEXIST E(11) /* File exists */
- { PVFS_EEXIST, "PVFS_EEXIST" },
-#define PVFS_ENODEV E(12) /* No such device */
- { PVFS_ENODEV, "PVFS_ENODEV" },
-#define PVFS_ENOTDIR E(13) /* Not a directory */
- { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
-#define PVFS_EISDIR E(14) /* Is a directory */
- { PVFS_EISDIR, "PVFS_EISDIR" },
-#define PVFS_EINVAL E(15) /* Invalid argument */
- { PVFS_EINVAL, "PVFS_EINVAL" },
-#define PVFS_EMFILE E(16) /* Too many open files */
- { PVFS_EMFILE, "PVFS_EMFILE" },
-#define PVFS_EFBIG E(17) /* File too large */
- { PVFS_EFBIG, "PVFS_EFBIG" },
-#define PVFS_ENOSPC E(18) /* No space left on device */
- { PVFS_ENOSPC, "PVFS_ENOSPC" },
-#define PVFS_EROFS E(19) /* Read-only file system */
- { PVFS_EROFS, "PVFS_EROFS" },
-#define PVFS_EMLINK E(20) /* Too many links */
- { PVFS_EMLINK, "PVFS_EMLINK" },
-#define PVFS_EPIPE E(21) /* Broken pipe */
- { PVFS_EPIPE, "PVFS_EPIPE" },
-#define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
- { PVFS_EDEADLK, "PVFS_EDEADLK" },
-#define PVFS_ENAMETOOLONG E(23) /* File name too long */
- { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
-#define PVFS_ENOLCK E(24) /* No record locks available */
- { PVFS_ENOLCK, "PVFS_ENOLCK" },
-#define PVFS_ENOSYS E(25) /* Function not implemented */
- { PVFS_ENOSYS, "PVFS_ENOSYS" },
-#define PVFS_ENOTEMPTY E(26) /* Directory not empty */
- { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
-#define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
- { PVFS_ELOOP, "PVFS_ELOOP" },
-#define PVFS_EWOULDBLOCK E(28) /* Operation would block */
- { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
-#define PVFS_ENOMSG E(29) /* No message of desired type */
- { PVFS_ENOMSG, "PVFS_ENOMSG" },
-#define PVFS_EUNATCH E(30) /* Protocol driver not attached */
- { PVFS_EUNATCH, "PVFS_EUNATCH" },
-#define PVFS_EBADR E(31) /* Invalid request descriptor */
- { PVFS_EBADR, "PVFS_EBADR" },
-#define PVFS_EDEADLOCK E(32)
- { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
-#define PVFS_ENODATA E(33) /* No data available */
- { PVFS_ENODATA, "PVFS_ENODATA" },
-#define PVFS_ETIME E(34) /* Timer expired */
- { PVFS_ETIME, "PVFS_ETIME" },
-#define PVFS_ENONET E(35) /* Machine is not on the network */
- { PVFS_ENONET, "PVFS_ENONET" },
-#define PVFS_EREMOTE E(36) /* Object is remote */
- { PVFS_EREMOTE, "PVFS_EREMOTE" },
-#define PVFS_ECOMM E(37) /* Communication error on send */
- { PVFS_ECOMM, "PVFS_ECOMM" },
-#define PVFS_EPROTO E(38) /* Protocol error */
- { PVFS_EPROTO, "PVFS_EPROTO" },
-#define PVFS_EBADMSG E(39) /* Not a data message */
- { PVFS_EBADMSG, "PVFS_EBADMSG" },
-#define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
- { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
-#define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
- { PVFS_ERESTART, "PVFS_ERESTART" },
-#define PVFS_EMSGSIZE E(42) /* Message too long */
- { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
-#define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
- { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
-#define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
- { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
-#define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
- { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
-#define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
- { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
-#define PVFS_EADDRINUSE E(47) /* Address already in use */
- { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
-#define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
- { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
-#define PVFS_ENETDOWN E(49) /* Network is down */
- { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
-#define PVFS_ENETUNREACH E(50) /* Network is unreachable */
- { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
-#define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
- { PVFS_ENETRESET, "PVFS_ENETRESET" },
-#define PVFS_ENOBUFS E(52) /* No buffer space available */
- { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
-#define PVFS_ETIMEDOUT E(53) /* Connection timed out */
- { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
-#define PVFS_ECONNREFUSED E(54) /* Connection refused */
- { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
-#define PVFS_EHOSTDOWN E(55) /* Host is down */
- { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
-#define PVFS_EHOSTUNREACH E(56) /* No route to host */
- { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
-#define PVFS_EALREADY E(57) /* Operation already in progress */
- { PVFS_EALREADY, "PVFS_EALREADY" },
-#define PVFS_EACCES E(58) /* Operation already in progress */
- { PVFS_EACCES, "PVFS_EACCES" },
- { 0, NULL }
-};
-
-static int
-dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- gint32 err;
- const char *errmsg = NULL;
-
- err = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
- offset += 4;
-
- if ((err != 0) && check_col(pinfo->cinfo, COL_INFO))
- {
- errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
- col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
- }
-
- return offset;
-}
-
-static int
-dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
- int offset)
-{
- proto_item *item = NULL;
- proto_tree *hcred_tree = NULL;
- guint32 uid = 0, gid = 0;
-
- uid = tvb_get_letohl(tvb, offset);
- gid = tvb_get_letohl(tvb, offset + 4);
-
- if (parent_tree)
- {
- item = proto_tree_add_text(parent_tree, tvb, offset, 8,
- "Credentials (UID: %d, GID: %d)", uid, gid);
-
- if (item)
- hcred_tree = proto_item_add_subtree(item, ett_pvfs_credentials);
- }
-
- /* UID */
- proto_tree_add_text(hcred_tree, tvb, offset, 4, "UID: %d", uid);
- offset += 4;
-
- /* GID */
- proto_tree_add_text(hcred_tree, tvb, offset, 4, "GID: %d", gid);
- offset += 4;
-
- return offset;
-}
-
-static const value_string names_pvfs_attr[] =
-{
-#define PVFS_ATTR_COMMON_UID (1 << 0)
-#define PVFS_ATTR_BIT_COMMON_UID 0
- { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
-
-#define PVFS_ATTR_COMMON_GID (1 << 1)
-#define PVFS_ATTR_BIT_COMMON_GID 1
- { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
-
-#define PVFS_ATTR_COMMON_PERM (1 << 2)
-#define PVFS_ATTR_BIT_COMMON_PERM 2
- { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
-
-#define PVFS_ATTR_COMMON_ATIME (1 << 3)
-#define PVFS_ATTR_BIT_COMMON_ATIME 3
- { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
-
-#define PVFS_ATTR_COMMON_CTIME (1 << 4)
-#define PVFS_ATTR_BIT_COMMON_CTIME 4
- { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
-
-#define PVFS_ATTR_COMMON_MTIME (1 << 5)
-#define PVFS_ATTR_BIT_COMMON_MTIME 5
- { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
-
-#define PVFS_ATTR_COMMON_TYPE (1 << 6)
-#define PVFS_ATTR_BIT_COMMON_TYPE 6
- { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
-
-#if 0
-#define PVFS_ATTR_COMMON_ALL \
- (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
- PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
- PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
- PVFS_ATTR_COMMON_TYPE)
-#endif
-
-/* internal attribute masks for metadata objects */
-#define PVFS_ATTR_META_DIST (1 << 10)
-#define PVFS_ATTR_BIT_META_DIST 10
- { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
-
-#define PVFS_ATTR_META_DFILES (1 << 11)
-#define PVFS_ATTR_BIT_META_DFILES 11
- { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
-
-#if 0
-#define PVFS_ATTR_META_ALL \
- (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
-#endif
-
-/* internal attribute masks for datafile objects */
-#define PVFS_ATTR_DATA_SIZE (1 << 15)
-#define PVFS_ATTR_BIT_DATA_SIZE 15
- { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
-
-#if 0
-#define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
-#endif
-
-/* internal attribute masks for symlink objects */
-#define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
-#define PVFS_ATTR_BIT_SYMLINK_TARGET 18
- { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
-
-#if 0
-#define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
-#endif
-
-/* internal attribute masks for directory objects */
-#define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
-#define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
- { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
-
-#if 0
-#define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
-#endif
-
-/* attribute masks used by system interface callers */
-#define PVFS_ATTR_SYS_SIZE (1 << 20)
-#define PVFS_ATTR_BIT_SYS_SIZE 20
- { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
-
-#define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
-#define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
- { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
-
-#define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
-#define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
- { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
-
-#define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
-#define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
- { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
-
-#if 0
-#define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
-#define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
-#define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
-#define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
-#define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
-#define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
-#define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
-#endif
- { 0, NULL }
-};
-
-#if 0
-#define PVFS_ATTR_SYS_ALL \
- (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
- PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
- PVFS_ATTR_SYS_DIRENT_COUNT)
-
-#define PVFS_ATTR_SYS_ALL_NOSIZE \
- (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
- PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
-
-#define PVFS_ATTR_SYS_ALL_SETABLE \
- (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
-#endif
-
-
-static int
-dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
- guint32 *pattrmask)
-{
- guint32 attrmask = 0, i = 0;
- proto_item *attritem = NULL;
- proto_tree *attrtree = NULL;
-
- attrmask = tvb_get_letohl(tvb, offset);
-
- attritem = proto_tree_add_text(tree, tvb, offset, 4,
- "Attribute Mask: %d", attrmask);
-
- if (attritem)
- attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
-
- for (i = 0; i < 32; i++)
- {
- if (attrmask & (1 << i))
- proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
- }
-
- offset += 4;
-
- if (pattrmask)
- *pattrmask = attrmask;
-
- return offset;
-}
-
-static const value_string names_pvfs_ds_type[] = {
-#define PVFS_TYPE_NONE 0
- { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
-#define PVFS_TYPE_METAFILE (1 << 0)
- { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
-#define PVFS_TYPE_DATAFILE (1 << 1)
- { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
-#define PVFS_TYPE_DIRECTORY (1 << 2)
- { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
-#define PVFS_TYPE_SYMLINK (1 << 3)
- { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
-#define PVFS_TYPE_DIRDATA (1 << 4)
- { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
- { 0, NULL }
-};
-
-static int
-dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
- int *pds_type)
-{
- guint32 ds_type = 0;
-
- ds_type = tvb_get_letohl(tvb, offset);
-
- if (tree)
- proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
-
- offset += 4;
-
- if (pds_type)
- *pds_type = ds_type;
-
- return offset;
-}
-
-#define roundup4(x) (((x) + 3) & ~3)
-#define roundup8(x) (((x) + 7) & ~7)
-
-static int
-dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
- proto_tree *tree,
- packet_info *pinfo _U_,
- int hfindex,
- gboolean fixed_length, guint32 length,
- gboolean string_data, char **string_buffer_ret)
-{
- int data_offset;
- proto_item *string_item = NULL;
- proto_tree *string_tree = NULL;
-
- guint32 string_length;
- guint32 string_length_full;
- guint32 string_length_packet;
- guint32 string_length_captured;
- guint32 string_length_copy;
-
- int fill_truncated;
- guint32 fill_length;
- guint32 fill_length_packet;
- guint32 fill_length_captured;
- guint32 fill_length_copy;
-
- int exception = 0;
-
- char *string_buffer = NULL;
- char *string_buffer_print = NULL;
-
- if (fixed_length) {
- string_length = length;
- data_offset = offset;
- } else {
- string_length = tvb_get_letohl(tvb,offset+0);
- data_offset = offset + 4;
-
- /*
- * Variable-length strings include NULL terminator on-the-wire but
- * NULL terminator is not included in string length.
- */
-
- if (string_data)
- string_length += 1;
- }
-
- string_length_captured = tvb_length_remaining(tvb, data_offset);
- string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
-
- /*
- * Strangeness... the protocol basically says that the length plus
- * the string must be padded out to an 8-byte boundary.
- */
-
- if (!string_data)
- string_length_full = roundup4(string_length);
- else
- string_length_full = roundup8(4 + string_length);
-
- if (string_length_captured < string_length) {
- /* truncated string */
- string_length_copy = string_length_captured;
- fill_truncated = 2;
- fill_length = 0;
- fill_length_copy = 0;
-
- if (string_length_packet < string_length)
- exception = ReportedBoundsError;
- else
- exception = BoundsError;
- }
- else {
- /* full string data */
- string_length_copy = string_length;
-
- if (!string_data)
- fill_length = string_length_full - string_length;
- else
- fill_length = string_length_full - string_length - 4;
-
- fill_length_captured = tvb_length_remaining(tvb,
- data_offset + string_length);
- fill_length_packet = tvb_reported_length_remaining(tvb,
- data_offset + string_length);
-
- if (fill_length_captured < fill_length) {
- /* truncated fill bytes */
- fill_length_copy = fill_length_packet;
- fill_truncated = 1;
- if (fill_length_packet < fill_length)
- exception = ReportedBoundsError;
- else
- exception = BoundsError;
- }
- else {
- /* full fill bytes */
- fill_length_copy = fill_length;
- fill_truncated = 0;
- }
- }
-
- if (string_data) {
- char *tmpstr;
-
- tmpstr = (char *) tvb_get_ephemeral_string(tvb, data_offset,
- string_length_copy);
-
- string_buffer = memcpy(ep_alloc(string_length_copy+1), tmpstr, string_length_copy);
- } else {
- string_buffer = (char *) tvb_memcpy(tvb,
- ep_alloc(string_length_copy+1), data_offset, string_length_copy);
- }
-
- string_buffer[string_length_copy] = '\0';
-
- /* calculate a nice printable string */
- if (string_length) {
- if (string_length != string_length_copy) {
- if (string_data) {
- char *formatted;
- guint16 string_buffer_size = 0;
-
- formatted = format_text((guint8 *)string_buffer,
- strlen(string_buffer));
-
- string_buffer_size = strlen(formatted) + 12 + 1;
-
- /* alloc maximum data area */
- string_buffer_print = (char*) ep_alloc(string_buffer_size);
- /* copy over the data */
- g_snprintf(string_buffer_print, string_buffer_size - 1,
- "%s<TRUNCATED>", formatted);
- /* append <TRUNCATED> */
- /* This way, we get the TRUNCATED even
- in the case of totally wrong packets,
- where \0 are inside the string.
- TRUNCATED will appear at the
- first \0 or at the end (where we
- put the securing \0).
- */
- } else {
- string_buffer_print="<DATA><TRUNCATED>";
- }
- } else {
- if (string_data) {
- string_buffer_print = (char *)
- ep_strdup(format_text((guint8 *) string_buffer,
- strlen(string_buffer)));
- } else {
- string_buffer_print="<DATA>";
- }
- }
- } else {
- string_buffer_print="<EMPTY>";
- }
-
- if (tree) {
- string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
- "%s: %s", proto_registrar_get_name(hfindex),
- string_buffer_print);
-
- if (string_item)
- string_tree = proto_item_add_subtree(string_item,
- ett_pvfs_string);
- }
- if (!fixed_length) {
- if (string_tree)
- proto_tree_add_text(string_tree, tvb,offset+0,4,
- "length: %u (excl. NULL terminator)", string_length - 1);
- offset += 4;
- }
-
- if (string_tree) {
- if (string_data) {
- proto_tree_add_string_format(string_tree,
- hfindex, tvb, offset, string_length_copy,
- string_buffer,
- "contents: %s", string_buffer_print);
- } else {
- proto_tree_add_bytes_format(string_tree,
- hfindex, tvb, offset, string_length_copy,
- (guint8 *) string_buffer,
- "contents: %s", string_buffer_print);
- }
- }
-
- offset += string_length_copy;
-
- if (fill_length) {
- if (string_tree) {
- if (fill_truncated) {
- proto_tree_add_text(string_tree, tvb,
- offset,fill_length_copy,
- "fill bytes: opaque data<TRUNCATED>");
- }
- else {
- proto_tree_add_text(string_tree, tvb,
- offset,fill_length_copy,
- "fill bytes: opaque data");
- }
- }
- offset += fill_length_copy;
- }
-
- if (string_item)
- proto_item_set_end(string_item, tvb, offset);
-
- if (string_buffer_ret != NULL)
- *string_buffer_ret = string_buffer_print;
-
- /*
- * If the data was truncated, throw the appropriate exception,
- * so that dissection stops and the frame is properly marked.
- */
- if (exception != 0)
- THROW(exception);
-
- return offset;
-}
-
-static int
-dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
- int offset, char **string_buffer_ret)
-{
- return dissect_pvfs_opaque_data(tvb, offset, tree, NULL, hfindex,
- FALSE, 0, TRUE, string_buffer_ret);
-}
-
-static void
-dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
-{
- guint sublen;
- guint bytes_left;
- gboolean first_line;
-
- bytes_left = PVFS2_FH_LENGTH;
- first_line = TRUE;
- while (bytes_left != 0) {
- sublen = 16;
- if (sublen > bytes_left)
- sublen = bytes_left;
- proto_tree_add_text(tree, tvb, offset, sublen,
- "%s%s",
- first_line ? "data: " :
- " ",
- tvb_bytes_to_str(tvb,offset,sublen));
- bytes_left -= sublen;
- offset += sublen;
- first_line = FALSE;
- }
-}
-
-static void
-dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, guint32 *hash)
-{
- guint32 fhhash;
- guint32 i;
-
- /* Not all bytes there. Any attempt to deduce the type would be
- senseless. */
- if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
- goto type_ready;
-
- /* create a semiunique hash value for the filehandle */
- for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
- guint32 val;
- val = tvb_get_ntohl(tvb, offset+i);
- fhhash ^= val;
- fhhash += val;
- }
-
- proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
- fhhash);
-
- if (hash)
- *hash = fhhash;
-
- /* TODO: add file name snooping code here */
-
-type_ready:
- dissect_fhandle_data_unknown(tvb, offset, tree);
-}
-
-static int
-dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, const char *name, guint32 *hash)
-{
- proto_item* fitem = NULL;
- proto_tree* ftree = NULL;
-
- if (tree)
- {
- fitem = proto_tree_add_text(tree, tvb, offset, PVFS2_FH_LENGTH,
- "%s", name);
-
- if (fitem)
- ftree = proto_item_add_subtree(fitem, ett_pvfs_fh);
- }
-
- /* TODO: add fh to file name snooping code here */
-
- proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
- PVFS2_FH_LENGTH);
-
- dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
-
- offset += PVFS2_FH_LENGTH;
-
- return offset;
-}
-
-static int
-dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo, guint32 nCount)
-{
- proto_item *extent_item = NULL;
- proto_tree *extent_tree = NULL;
-
- if (tree)
- {
- extent_item = proto_tree_add_text(tree, tvb, offset, 8,
- "Item %d", nCount);
-
- if (extent_item)
- extent_tree = proto_item_add_subtree(extent_item,
- ett_pvfs_extent_item);
- }
-
- /* first handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
- NULL);
-
- /* last handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
- NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint32 extent_count = 0;
- guint32 nCount;
- proto_item *extent_array_item = NULL;
- proto_tree *extent_array_tree = NULL;
-
- /* extent count */
- extent_count = tvb_get_letohl(tvb, offset);
-
- if (tree)
- extent_array_item = proto_tree_add_text(tree, tvb, offset, 4,
- "Handle Extent Array (count = %d)", extent_count);
-
- offset += 4;
-
- if (extent_count > 0)
- {
- if (extent_array_item)
- extent_array_tree = proto_item_add_subtree(extent_array_item,
- ett_pvfs_extent_array_tree);
-
- /* Add extent array items */
- for (nCount = 0; nCount < extent_count; nCount++)
- offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
- pinfo, nCount);
- }
-
- return offset;
-}
-
-static int
-dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
- int hf_time, int hf_time_sec, int hf_time_nsec)
-{
- guint32 seconds;
- guint32 nseconds;
- nstime_t ts;
- proto_item *time_item = NULL;
- proto_tree *time_tree = NULL;
-
- ts.secs = seconds = tvb_get_letohl(tvb, offset);
- ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
-
- if (tree)
- {
- time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
-
- if (time_item)
- time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
- }
-
- if (time_tree)
- {
- proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
- proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4,
- nseconds);
- }
-
- offset += 8;
- return offset;
-}
-
-static
-int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
- int hfindex, guint64 *pvalue)
-{
- guint64 val;
-
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
-
- proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
-
- if (pvalue)
- *pvalue = val;
-
- return offset + 8;
-}
-
-/* Taken from pvfs2-dist-simple-stripe.h */
-#define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
-#define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
-
-static int
-dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- proto_item *dist_item = NULL;
- proto_tree *dist_tree = NULL;
- char *distname = NULL;
- guint32 distlen = 0;
- char *tmpstr = NULL;
- guint8 issimplestripe = 0;
-
- /* Get distribution name length */
- distlen = tvb_get_letohl(tvb, offset);
-
- /* Get distribution name */
- tmpstr = (char *) tvb_get_ephemeral_string(tvb, offset + 4, distlen);
-
- if (tree)
- {
- guint32 total_len;
-
- /* 'distlen' does not include the NULL terminator */
- total_len = roundup8(4 + distlen + 1);
-
- if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
- (strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
- distlen) == 0))
- {
- /* Parameter for 'simple_stripe' is 8 bytes */
- total_len += 8;
-
- issimplestripe = 1;
- }
-
- dist_item = proto_tree_add_text(tree, tvb, offset, total_len + 8,
- "Distribution: %s", tmpstr);
-
- if (dist_item)
- dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
- }
-
- /* io_dist */
- offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
- &distname);
-
- /* TODO: only one distribution type is currently supported */
- if (issimplestripe)
- offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
- hf_pvfs_strip_size, NULL);
-
- offset += 8;
-
- return offset;
-}
-
-static int
-dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint32 dfile_count, i;
-
- /* dfile_count */
- dfile_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "dfile_count: %d",
- dfile_count);
- offset += 4;
-
- for (i = 0; i < dfile_count; i++)
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- gint32 ds_type = 0;
- guint32 attrmask = 0;
- proto_item *attr_item = NULL;
- proto_tree *attr_tree = NULL;
-
- if (tree)
- {
- attr_item = proto_tree_add_text(tree, tvb, offset, -1, "Attributes");
-
- if (attr_item)
- attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr_tree);
- }
-
- /* UID */
- proto_tree_add_text(attr_tree, tvb, offset, 4, "UID: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* GID */
- proto_tree_add_text(attr_tree, tvb, offset, 4, "GID: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* Permissions */
- proto_tree_add_text(attr_tree, tvb, offset, 4, "Permissions: %o",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset += 4;
-
- /* atime */
- offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
- hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
-
- /* mtime */
- offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
- hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
-
- /* ctime */
- offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
- hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
-
- /* attrmask */
- offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
-
- /* objtype */
- offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
-
- if (attrmask & PVFS_ATTR_META_DIST)
- {
- offset = dissect_pvfs_distribution(tvb, attr_tree, offset);
-
- offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
- }
- else
- {
- if (attrmask & PVFS_ATTR_META_DFILES)
- {
- offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
- }
- else
- {
- if (attrmask & PVFS_ATTR_DATA_SIZE)
- {
- offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
- NULL);
- }
- else
- {
- if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
- {
- /* target_path_len */
- proto_tree_add_text(attr_tree, tvb, offset, 4,
- "target_path_len: %d", tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset += 4;
-
- /* target_path */
- offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
- offset, NULL);
- }
- else
- {
- if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
- {
- offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
- hf_pvfs_size, NULL);
- }
- }
- }
- }
- }
-
- return offset;
-}
-
-static int
-dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- proto_tree_add_uint(tree, hf_pvfs_io_type, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- proto_tree_add_uint(tree, hf_pvfs_flowproto_type, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint32 server_param = 0;
- guint32 lowpart;
-
- /* server_param */
- server_param = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
- server_param);
- offset += 4;
-
- switch (server_param)
- {
- case PVFS_SERV_PARAM_MODE:
- lowpart = tvb_get_letohl(tvb, offset);
-
- proto_tree_add_text(tree, tvb, offset, 8,
- "Server Mode: %s (%u)",
- val_to_str(lowpart, names_pvfs_server_mode, "%u"), lowpart);
- break;
-
- case PVFS_SERV_PARAM_FSID_CHECK:
- lowpart = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4, lowpart);
- proto_tree_add_uint(tree, hf_pvfs_unused, tvb, offset + 4, 4,
- tvb_get_letohl(tvb, offset + 4));
- break;
-
- case PVFS_SERV_PARAM_ROOT_CHECK:
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
- break;
- }
-
- offset += 8;
-
- return offset;
-}
-
-static int
-dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- if (tree)
- proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
-
- offset += 4;
-
- return offset;
-}
-
-/*
- * =======================================================================
- * Request handlers
- * =======================================================================
- */
-
-static int
-dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* type */
- offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
-
- offset += 4;
-
- offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- guint64 val = 0;
- gint32 ereg, sreg;
-
- /* offset */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
- offset += 8;
-
- /* TODO: num_eregs */
- proto_tree_add_uint(tree, hf_pvfs_num_eregs, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* TODO: num_blocks */
- proto_tree_add_uint(tree, hf_pvfs_num_blocks, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* TODO: stride */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_stride, tvb, offset, 8, val);
- offset += 8;
-
- /* TODO: ub */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_ub, tvb, offset, 8, val);
- offset += 8;
-
- /* TODO: lb */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_lb, tvb, offset, 8, val);
- offset += 8;
-
- /* TODO: aggregate size */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_aggregate_size, tvb, offset, 8, val);
- offset += 8;
-
- /* num_contig_chunks */
- proto_tree_add_uint(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* depth */
- proto_tree_add_text(tree, tvb, offset, 4, "depth: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* num_nested_req */
- proto_tree_add_text(tree, tvb, offset, 4, "num_nested_req: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* committed */
- proto_tree_add_text(tree, tvb, offset, 4, "committed: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* refcount */
- proto_tree_add_text(tree, tvb, offset, 4, "refcount: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* documented */
- offset += 4;
-
- /* ereg */
- ereg = tvb_get_letohl(tvb, offset);
- proto_tree_add_int(tree, hf_pvfs_ereg, tvb, offset, 4, ereg);
- offset += 4;
-
- /* sreg */
- sreg = tvb_get_letohl(tvb, offset);
- proto_tree_add_int(tree, hf_pvfs_sreg, tvb, offset, 4, sreg);
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint64 val;
-
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* skip4 as per source code */
- offset += 4;
-
- /* io_type */
- offset = dissect_pvfs_io_type(tvb, tree, offset);
-
- /* flow_type */
- offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
-
- /* server_nr */
- proto_tree_add_uint(tree, hf_pvfs_server_nr, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* server_ct */
- proto_tree_add_uint(tree, hf_pvfs_server_count, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* Distribution */
- offset = dissect_pvfs_distribution(tvb, tree, offset);
-
- proto_tree_add_text(tree, tvb, offset, 4, "numreq: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* */
- offset += 4;
-
- offset = dissect_pvfs_pint_request(tvb, tree, offset);
-
- /* TODO: remove this!!! */
- offset = tvb_length(tvb) - 16;
-
- /* offset */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
- offset += 8;
-
- /* size */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
- offset += 8;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* attrmask */
- offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* parent_ref: fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
-
- return offset;
-}
-
-/* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
-static int
-dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* Path */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- /* starting_handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* attribute mask */
- offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* Filename */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
-
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
-
- /* parent_handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- /* atime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
- hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
-
- /* mtime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
- hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
-
- /* ctime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
- hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
-
- return offset;
-}
-
-/* TODO: incomplete */
-static int
-dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* path */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
-
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- /* atime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
- hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
-
- /* mtime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
- hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
-
- /* ctime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
- hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* path */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
-
- /* New directory entry handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
- NULL);
-
- /* Parent handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* Parent atime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
- hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
-
- /* Parent mtime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
- hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
-
- /* Parent ctime */
- offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
- hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint64 val;
-
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- /* size */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
- offset += 8;
-
- /* TODO: flags */
- proto_tree_add_text(tree, tvb, offset, 4, "flags: %u",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint count, i;
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- /* attr */
- offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
-
- /* handle_extent_array */
- count = tvb_get_letohl(tvb, offset);
- offset += 4;
-
- for (i = 0; i < count; i++)
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* object_ref: handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* object_ref: fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* ds_position */
- proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* dirent_limit */
- proto_tree_add_text(tree, tvb, offset, 4, "dirent_limit: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* flags */
- proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* server_param */
- offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo _U_)
-{
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
- int offset, packet_info *pinfo _U_)
-{
- /* TODO: next_id */
- proto_tree_add_text(tree, tvb, offset, 4, "next_id: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* TODO: count */
- proto_tree_add_text(tree, tvb, offset, 4, "count: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
- proto_tree *tree, int offset, packet_info *pinfo)
-{
- guint32 handle_count, i;
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* handle count */
- handle_count = tvb_get_letohl(tvb, offset);
- offset += 4;
-
- for (i = 0; i < handle_count; i++)
- {
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
- }
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo _U_)
-{
- /* event_count */
- proto_tree_add_text(tree, tvb, offset, 4, "Event count: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
- proto_tree *tree, int offset, packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* */
- offset += 4;
-
- /* entry */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
- proto_tree *tree, int offset, packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- return offset;
-}
-
-/* TODO: untested/incomplete */
-static int
-dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- /* attribute key */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
- NULL);
-
- /* attribute value */
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
- NULL);
-
- return offset;
-}
-
-/* TODO: incomplete/untested */
-static int
-dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- guint32 nKey, i;
-
- /* number of keys and vals */
- nKey = tvb_get_letohl(tvb, offset);
- offset += 4;
-
- for (i = 0; i < nKey; i++)
- offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
-
- return offset;
-}
-
-/* TODO: incomplete/untested */
-static int
-dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- offset = dissect_ds_keyval_array(tvb, tree, offset);
-
- return offset;
-}
-
-/* TODO: incomplete/untested */
-static int
-dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- offset += 4;
-
- offset = dissect_ds_keyval_array(tvb, tree, offset);
-
- return offset;
-}
-
-/* TODO: untested */
-static int
-dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* key */
- offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_release_number(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- guint32 release_nr = tvb_get_letohl(tvb, offset);
-
- proto_tree_add_text(tree, tvb, offset, 4,
- "PVFS2 Release Number: %d (%d.%d.%d)",
- release_nr,
- release_nr / 10000,
- (release_nr % 10000) / 100,
- (release_nr % 10000) % 100);
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- /* PVFS release number */
- offset = dissect_pvfs2_release_number(tvb, tree, offset);
-
- /* wire encoding type */
- proto_tree_add_uint(tree, hf_pvfs_encoding, tvb, offset,
- 4, tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* server op */
- proto_tree_add_uint(tree, hf_pvfs_server_op, tvb, offset, 4,
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo, guint32 server_op)
-{
- /* context_id */
- proto_tree_add_uint(tree, hf_pvfs_context_id, tvb, offset,
- 4, tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* credentials */
- offset = dissect_pvfs_credentials(tvb, tree, offset);
-
- switch (server_op)
- {
- case PVFS_SERV_CREATE:
- offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_REMOVE:
- offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_IO:
- offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_GETATTR:
- offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_SETATTR:
- offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_LOOKUP_PATH:
- offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_CRDIRENT:
- offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_RMDIRENT:
- offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_CHDIRENT:
- offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_TRUNCATE:
- offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_MKDIR:
- offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_READDIR:
- offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_GETCONFIG:
- /* No parameters in request */
- break;
-#endif
-
-#if 0
- case PVFS_SERV_WRITE_COMPLETION:
- /* No parameters in request */
- break;
-#endif
-
- case PVFS_SERV_FLUSH:
- offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_MGMT_SETPARAM:
- offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
- pinfo);
- break;
-
-#if 0
- case PVFS_SERV_MGMT_NOOP:
- /* No parameters in request */
- break;
-#endif
-
- case PVFS_SERV_STATFS:
- offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_PERF_UPDATE:
- /* No parameters in request */
- break;
-#endif
-
- case PVFS_SERV_MGMT_PERF_MON:
- offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
- pinfo);
- break;
-
- case PVFS_SERV_MGMT_ITERATE_HANDLES:
- offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
- offset, pinfo);
- break;
-
- case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
- offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
- offset, pinfo);
- break;
-
- case PVFS_SERV_MGMT_EVENT_MON:
- offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
- pinfo);
- break;
-
- case PVFS_SERV_MGMT_REMOVE_OBJECT:
- offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
- pinfo);
- break;
-
- case PVFS_SERV_MGMT_REMOVE_DIRENT:
- offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
- pinfo);
- break;
-
- case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
- offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
- offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_JOB_TIMER:
- /* No parameters in request */
- break;
-#endif
-
- case PVFS_SERV_PROTO_ERROR:
- /* TODO: is this necessary? */
- break;
-
- case PVFS_SERV_GETEATTR:
- offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_SETEATTR:
- offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_DELEATTR:
- offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
- break;
-
- default:
- /* TODO: what should we do here? */
- break;
- }
-
- return offset;
-}
-
-/*
- * =======================================================================
- * Response handlers
- * =======================================================================
- */
-
-static int
-dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* Handle */
- return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-}
-
-static int
-dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
-}
-
-static int
-dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- guint32 nCount = 0;
- guint32 handle_count = 0;
- guint32 attr_count = 0;
- proto_item *attr_item = NULL;
- proto_tree *attr_tree = NULL;
-
- offset += 4;
-
- /* handle_count */
- handle_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "Handle Count: %d",
- handle_count);
- offset += 4;
-
- /* TODO: add bounds checking */
- for (nCount = 0; nCount < handle_count; nCount++)
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- offset += 4;
-
- /* array of attributes */
- attr_count = tvb_get_letohl(tvb, offset);
-
- if (tree)
- {
- attr_item = proto_tree_add_text(tree, tvb, offset, 4,
- "Attribute array (total items: %d)", attr_count);
-
- if (attr_item)
- attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr);
- }
-
- offset += 4;
-
- /* Array of attributes */
- for (nCount = 0; nCount < attr_count; nCount++)
- offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- /* Handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- guint64 val;
- guint32 dirent_count = 0;
- guint32 nCount = 0;
-
- /* ds_position */
- proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset += 4;
-
- /* directory_version */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
- proto_tree_add_uint64(tree, hf_pvfs_directory_version, tvb, offset, 8,
- val);
- offset += 8;
-
- offset += 4;
-
- /* dirent_count */
- dirent_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "dirent_count: %d",
- dirent_count);
- offset += 4;
-
- for (nCount = 0; nCount < dirent_count; nCount++)
- {
- offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
- }
-
- return offset;
-}
-
-/*
- * TODO: this code needs work! Not finished yet!
- */
-static int
-dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
- int offset)
-{
- guint32 i;
- guint32 total_bytes = 0, total_config_bytes = 0, total_lines = 0;
- guint32 bytes_processed = 0;
- guint32 length_remaining = 0;
- char *ptr = NULL;
- proto_item *item = NULL, *config_item = NULL;
- proto_tree *tree = NULL, *config_tree = NULL;
- guint8 truncated = 0;
-
- if (parent_tree)
- {
- item = proto_tree_add_text(parent_tree, tvb, offset, 12,
- "Server Config");
-
- if (item)
- tree = proto_item_add_subtree(item, ett_pvfs_server_config);
- }
-
- /* Total number of bytes in server config (incl. entry count) */
- total_bytes = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "Total Bytes: %d",
- total_bytes);
- offset += 4;
-
- /* There must be at least 4 bytes of data returned to determine the
- * size of the server config data
- */
- if (total_bytes < 4)
- {
- /* Server config not returned, bail out */
- return offset;
- }
-
- /* Number of entries in server config */
- total_lines = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "Lines: %d", total_lines);
- offset += 4;
-
- /* Number of bytes in server config */
- total_config_bytes = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "Config Bytes: %d",
- total_config_bytes);
- offset += 4;
-
- /* Get pointer to server config data */
- ptr = (char *) tvb_get_ptr(tvb, offset, total_config_bytes);
-
- /* Check if all data is available */
- length_remaining = tvb_length_remaining(tvb, offset);
-
- if (length_remaining < total_config_bytes)
- {
- total_config_bytes = length_remaining;
-
- truncated = 1;
- }
-
- bytes_processed = 0;
-
- for (i = 0; i < total_lines; i++)
- {
- guint8 entry[256], *pentry = entry, *tmp_entry = NULL;
- guint32 entry_length = 0, tmp_entry_length = 0;
- guint32 bufsiz = sizeof(entry);
-
- while ((*ptr != '\n') && (*ptr != '\0') &&
- (bytes_processed < total_config_bytes) &&
- (entry_length < bufsiz))
- {
- *pentry++ = *ptr++;
-
- bytes_processed++;
- entry_length++;
- }
-
- if ((entry_length == bufsiz) &&
- ((entry[entry_length - 1] != '\n') ||
- (entry[entry_length - 1] != '\0')))
- {
- /*
- * Single line of config data doesn't fit into provided buffer,
- * config data is malformed.
- */
-
- break;
- }
-
- if (bytes_processed == total_config_bytes)
- {
- /* Oops... ran out of data before we could complete the entry */
- break;
- }
-
- *pentry= '\0';
-
- tmp_entry = entry;
- tmp_entry_length = entry_length;
-
- /* Remove all whitespace from front of entry */
- while ((tmp_entry_length > 0) && (!isalnum(*tmp_entry)) &&
- (*tmp_entry != '<'))
- {
- tmp_entry++;
- tmp_entry_length--;
- }
-
- if (tmp_entry[0] == '<')
- {
- if (tmp_entry[tmp_entry_length - 1] == '>')
- {
- /* Token */
- if (tmp_entry[1] != '/')
- {
- /* Opening token, create new tree root */
- config_item = proto_tree_add_text(tree, tvb, offset,
- tmp_entry_length, "%s", tmp_entry);
-
- if (config_item)
- config_tree = proto_item_add_subtree(config_item,
- ett_pvfs_server_config_branch);
- }
- else
- {
- /* Closing token */
- config_item = NULL;
- config_tree = NULL;
- }
- }
- else
- {
- /* Malformed token */
- break;
- }
- }
- else
- {
- /* Insert items into the root config tree if there's no subtree
- * defined.
- */
- if (config_tree == NULL)
- config_tree = tree;
-
- if (tmp_entry_length > 0)
- {
- proto_tree_add_text(config_tree, tvb, offset, tmp_entry_length,
- "%s", tmp_entry);
- }
- }
-
- offset += entry_length + 1;
-
- ptr++;
- bytes_processed++;
- }
-
- if (bytes_processed < total_config_bytes)
- {
- /* We ran out of server config data */
- proto_tree_add_text(config_tree, tvb, offset, -1,
- "<MALFORMED OR TRUNCATED DATA>");
- }
-
- return offset;
-}
-
-static int
-dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
- int offset)
-{
- /* size */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
- NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
- int offset)
-{
- guint64 val;
-
- /* old_value */
- val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
- tvb_get_letohl(tvb, offset);
-
- proto_tree_add_uint64(tree, hf_pvfs_prev_value, tvb, offset, 8, val);
-
- offset += 8;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
-{
- offset += 4;
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- /* bytes_available */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
- NULL);
-
- /* bytes_total */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
- NULL);
-
- /* RAM bytes total */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
- NULL);
-
- /* RAM bytes free */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
- NULL);
-
- /* load average (1s) */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
- NULL);
-
- /* load average (5s) */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
- NULL);
-
- /* load average (15s) */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
- NULL);
-
- /* uptime (seconds) */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
- NULL);
-
- /* handles_available_count */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
- NULL);
-
- /* handles_total_count */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
- NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
- int nItem)
-{
- proto_item *stat_item = NULL;
- proto_tree *stat_tree = NULL;
-
- if (tree)
- {
- stat_item = proto_tree_add_text(tree, tvb, offset, 48,
- "Stat Array - Element %d", nItem);
-
- if (stat_item)
- stat_tree = proto_item_add_subtree(stat_item,
- ett_pvfs_mgmt_perf_stat);
- }
-
- /* TODO: valid_flag */
- proto_tree_add_text(stat_tree, tvb, offset, 4, "valid_flag: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* TODO: id */
- proto_tree_add_text(stat_tree, tvb, offset, 4, "id: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
- NULL);
- offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
- NULL);
- offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
- NULL);
- offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
- NULL);
- offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
- NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
- int offset)
-{
- guint32 perf_array_count, i;
-
- /* TODO: suggested_next_id */
- proto_tree_add_text(tree, tvb, offset, 4, "suggested_next_id: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset += 4;
-
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms,
- NULL);
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms,
- NULL);
-
- offset += 4;
-
- /* TODO: perf_array_count */
- perf_array_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "perf_array_count: %d",
- perf_array_count);
- offset += 4;
-
- for (i = 0; i < perf_array_count; i++)
- offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- guint32 handle_count, i;
-
- /* ds_position */
- proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* handle_count */
- handle_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "handle_count: %d",
- handle_count);
- offset += 4;
-
- /* TODO: this could be improved */
- for (i = 0; i < handle_count; i++)
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo)
-{
- offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
- offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
- NULL);
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
- NULL);
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- guint32 dspace_info_count, i;
- proto_item *arr_item = NULL;
- proto_tree *arr_tree = NULL;
-
- offset += 4;
-
- /* dspace_info_count */
- dspace_info_count = tvb_get_letohl(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 4, "dspace_info_count: %d",
- dspace_info_count);
-
- if ((dspace_info_count > 0) && (tree))
- {
- arr_item = proto_tree_add_text(tree, tvb, offset,
- dspace_info_count * 40, "dspace_info Array (%d items)",
- dspace_info_count);
-
- if (arr_item)
- arr_tree = proto_item_add_subtree(arr_item,
- ett_pvfs_mgmt_dspace_info);
- }
-
- for (i = 0; i < dspace_info_count; i++)
- offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
- int offset)
-{
- /* api */
- proto_tree_add_text(tree, tvb, offset, 4, "api: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* operation */
- proto_tree_add_text(tree, tvb, offset, 4, "operation: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* value */
- proto_tree_add_text(tree, tvb, offset, 4, "value: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* id */
- offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
- NULL);
-
- /* flags */
- proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* tv_sec */
- proto_tree_add_text(tree, tvb, offset, 4, "tv_sec: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- /* tv_usec */
- proto_tree_add_text(tree, tvb, offset, 4, "tv_usec: %d",
- tvb_get_letohl(tvb, offset));
- offset += 4;
-
- offset += 4;
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
- int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- /* fs_id */
- offset = dissect_pvfs_fs_id(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
- proto_tree *tree, int offset, packet_info *pinfo)
-{
- /* handle */
- offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
-
- return offset;
-}
-
-/* TODO: untested */
-static int
-dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo _U_)
-{
- offset += 4;
-
- /* Dissect nKey & ds_keyval array */
- offset = dissect_ds_keyval_array(tvb, tree, offset);
-
- return offset;
-}
-
-static int
-dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
- packet_info *pinfo, guint32 server_op)
-{
- /* error code */
- offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
-
- switch (server_op)
- {
- case PVFS_SERV_CREATE:
- offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_REMOVE:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_IO:
- offset = dissect_pvfs2_io_response(tvb, tree, offset);
- break;
-
- case PVFS_SERV_GETATTR:
- offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_SETATTR:
- /* No result data */
- break;
-
- case PVFS_SERV_LOOKUP_PATH:
- offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_CRDIRENT:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_RMDIRENT:
- offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_CHDIRENT:
- offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_TRUNCATE:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_MKDIR:
- offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_READDIR:
- offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
- break;
-
- case PVFS_SERV_GETCONFIG:
- offset = dissect_pvfs2_getconfig_response(tvb, tree, offset);
- break;
-
- case PVFS_SERV_WRITE_COMPLETION:
- offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
- break;
-
-#if 0
- case PVFS_SERV_FLUSH:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_MGMT_SETPARAM:
- offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
- break;
-
-#if 0
- case PVFS_SERV_MGMT_NOOP:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_STATFS:
- offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
- break;
-
-#if 0
- case PVFS_SERV_PERF_UPDATE:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_MGMT_PERF_MON:
- offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
- break;
-
- case PVFS_SERV_MGMT_ITERATE_HANDLES:
- offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
- offset, pinfo);
- break;
-
- case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
- offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
- offset, pinfo);
- break;
-
- case PVFS_SERV_MGMT_EVENT_MON:
- offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
- break;
-
- case PVFS_SERV_MGMT_REMOVE_OBJECT:
- offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
- pinfo);
- break;
-
-#if 0
- case PVFS_SERV_MGMT_REMOVE_DIRENT:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
- offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
- offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_JOB_TIMER:
- /* No result data */
- break;
-#endif
-
- case PVFS_SERV_PROTO_ERROR:
- /* No result data */
- break;
-
- /* TODO: untested */
- case PVFS_SERV_GETEATTR:
- offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
- break;
-
-#if 0
- case PVFS_SERV_SETEATTR:
- /* No result data */
- break;
-#endif
-
-#if 0
- case PVFS_SERV_DELEATTR:
- /* No result data */
- break;
-#endif
-
- default:
- /* TODO: what do we do here? */
- break;
- }
-
- return offset;
-}
-
-static GHashTable *pvfs2_io_tracking_value_table = NULL;
-
-typedef struct pvfs2_io_tracking_key
-{
- guint64 tag;
-} pvfs2_io_tracking_key_t;
-
-typedef struct pvfs2_io_tracking_value
-{
- guint32 request_frame_num;
- guint32 response_frame_num;
- guint32 flow_frame_num;
-
-} pvfs2_io_tracking_value_t;
-
-static gint
-pvfs2_io_tracking_equal(gconstpointer k1, gconstpointer k2)
-{
- const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
- const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
-
- return (key1->tag == key2->tag);
-}
-
-static guint
-pvfs2_io_tracking_hash(gconstpointer k)
-{
- const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
-
- return (key->tag >> 32) ^ ((guint32) key->tag);
-}
-
-static void
-pvfs2_io_tracking_init(void)
-{
- if (pvfs2_io_tracking_value_table != NULL)
- g_hash_table_destroy(pvfs2_io_tracking_value_table);
-
- pvfs2_io_tracking_value_table = g_hash_table_new(pvfs2_io_tracking_hash,
- pvfs2_io_tracking_equal);
-}
-
-static pvfs2_io_tracking_value_t *
-pvfs2_io_tracking_new_with_tag(guint64 tag, guint32 num)
-{
- pvfs2_io_tracking_value_t *value;
- pvfs2_io_tracking_key_t *newkey;
-
- newkey = (pvfs2_io_tracking_key_t *) se_alloc(sizeof(*newkey));
- memset(newkey, 0, sizeof(*newkey));
- newkey->tag = tag;
-
- value = se_alloc(sizeof(*value));
- memset(value, 0, sizeof(*value));
-
- g_hash_table_insert(pvfs2_io_tracking_value_table, newkey, value);
-
- value->request_frame_num = num;
-
- return value;
-}
-
-static gboolean
-dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
- gboolean dissect_other_as_continuation _U_)
-{
- guint32 mode = 0;
- proto_item *item = NULL, *hitem = NULL;
- proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
- int offset = 0;
- guint64 tag;
- guint32 server_op;
- pvfs2_io_tracking_value_t *val = NULL;
-
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
-
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
-
- if (parent_tree)
- {
- item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, FALSE);
-
- if (item)
- pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
- }
-
- proto_tree_add_text(pvfs_tree, tvb, 0, -1, "Version: 2");
-
- /* PVFS packet header is 24 bytes */
- hitem = proto_tree_add_text(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
- "BMI Header");
- if (hitem)
- pvfs_htree = proto_item_add_subtree(hitem, ett_pvfs_hdr);
-
- /* Magic number */
- proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, TRUE);
- offset += 4;
-
- /* TCP message mode (32-bit) */
- mode = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
- offset += 4;
-
- /* tag (64-bit) */
- offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
-
- /* size (64-bit) */
- offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
-
- /* Lookahead to get server_op (invalid if frame contains flow data) */
- server_op = tvb_get_letohl(tvb, offset + 8);
-
- if (mode == TCP_MODE_UNEXP)
- {
- /* Add entry to tracking table for PVFS_SERV_IO request */
- if ((server_op == PVFS_SERV_IO) && !pinfo->fd->flags.visited)
- val = pvfs2_io_tracking_new_with_tag(tag, pinfo->fd->num);
- }
- else
- {
- pvfs2_io_tracking_key_t key;
-
- memset(&key, 0, sizeof(key));
- key.tag = tag;
-
- val = g_hash_table_lookup(pvfs2_io_tracking_value_table, &key);
-
- /* If this frame contains a known PVFS_SERV_IO tag, track it */
- if (val && !pinfo->fd->flags.visited)
- {
- /* If response HAS NOT been seen, mark this frame as response */
- if (val->response_frame_num == 0)
- val->response_frame_num = pinfo->fd->num;
- else
- {
- /* If response HAS been seen, this frame is flow data */
- if (val->flow_frame_num == 0)
- val->flow_frame_num = pinfo->fd->num;
- }
- }
- }
-
- if (val && (val->flow_frame_num == pinfo->fd->num))
- {
- /* This frame is marked as being flow data */
- if (check_col(pinfo->cinfo, COL_INFO))
- col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
-
- proto_tree_add_text(pvfs_tree, tvb, offset, -1, "<data>");
-
- return TRUE;
- }
-
- /* Extract common part of packet found in requests and responses */
- offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
-
- /* Update column info display */
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_set_str(pinfo->cinfo, COL_INFO,
- val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
-
- col_append_fstr(pinfo->cinfo, COL_INFO,
- (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
- }
-
- /* TODO: handle all modes */
- if (mode == TCP_MODE_UNEXP)
- {
- /* Request */
- offset = dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
- }
- else
- {
- /* TODO: re-examine this! */
-#if 0
- if (mode == TCP_MODE_REND)
- {
- /*
- * TODO: move this code outside so it's common for requests and
- * responses
- */
-
- if (check_col(pinfo->cinfo, COL_INFO))
- col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
- }
- else
-#endif
- {
- /* Response */
- offset = dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
- server_op);
- }
- }
-
- return TRUE;
-}
-
-/* Register the protocol with Ethereal */
-void
-proto_register_pvfs(void)
-{
- static hf_register_info hf[] = {
- { &hf_pvfs_magic_nr,
- { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
- NULL, 0, "Magic Number", HFILL }},
-
- { &hf_pvfs_mode,
- { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_mode), 0, "Mode", HFILL }},
-
- { &hf_pvfs_tag,
- { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
- NULL, 0, "Tag", HFILL }},
-
- { &hf_pvfs_size,
- { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
- NULL, 0, "Size", HFILL }},
-
- { &hf_pvfs_release_number,
- { "Release Number", "pvfs.release_number", FT_UINT32, BASE_DEC,
- NULL, 0, "Release Number", HFILL }},
-
- { &hf_pvfs_encoding,
- { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_encoding), 0, "Encoding", HFILL }},
-
- { &hf_pvfs_server_op,
- { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_server_op), 0, "Server Operation", HFILL }},
-
- { &hf_pvfs_handle,
- { "Handle", "pvfs.handle", FT_BYTES, BASE_HEX,
- NULL, 0, "Handle", HFILL }},
-
- { &hf_pvfs_fs_id,
- { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
- NULL, 0, "File System ID", HFILL }},
-
- { &hf_pvfs_attrmask,
- { "attrmask", "pvfs.attrmask", FT_UINT32, BASE_HEX,
- NULL, 0, "Attribute Mask", HFILL }},
-
- { &hf_pvfs_attr,
- { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
- VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
-
- { &hf_pvfs_ds_type,
- { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
- VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
-
- { &hf_pvfs_error,
- { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
- VALS(names_pvfs_error), 0, "Result", HFILL }},
-
- { &hf_pvfs_atime,
- { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Access Time", HFILL }},
-
- { &hf_pvfs_atime_sec,
- { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Access Time (seconds)", HFILL }},
-
- { &hf_pvfs_atime_nsec,
- { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Access Time (microseconds)", HFILL }},
-
- { &hf_pvfs_mtime,
- { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Modify Time", HFILL }},
-
- { &hf_pvfs_mtime_sec,
- { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Modify Time (seconds)", HFILL }},
-
- { &hf_pvfs_mtime_nsec,
- { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Modify Time (microseconds)", HFILL }},
-
- { &hf_pvfs_ctime,
- { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Creation Time", HFILL }},
-
- { &hf_pvfs_ctime_sec,
- { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Creation Time (seconds)", HFILL }},
-
- { &hf_pvfs_ctime_nsec,
- { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Creation Time (microseconds)", HFILL }},
-
- { &hf_pvfs_parent_atime,
- { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Access Time", HFILL }},
-
- { &hf_pvfs_parent_atime_sec,
- { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Access Time (seconds)", HFILL }},
-
- { &hf_pvfs_parent_atime_nsec,
- { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Access Time (microseconds)", HFILL }},
-
- { &hf_pvfs_parent_mtime,
- { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Modify Time", HFILL }},
-
- { &hf_pvfs_parent_mtime_sec,
- { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Modify Time (seconds)", HFILL }},
-
- { &hf_pvfs_parent_mtime_nsec,
- { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Modify Time (microseconds)", HFILL }},
-
- { &hf_pvfs_parent_ctime,
- { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, BASE_NONE,
- NULL, 0, "Creation Time", HFILL }},
-
- { &hf_pvfs_parent_ctime_sec,
- { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
- NULL, 0, "Creation Time (seconds)", HFILL }},
-
- { &hf_pvfs_parent_ctime_nsec,
- { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
- NULL, 0, "Creation Time (microseconds)", HFILL }},
-
- { &hf_pvfs_dirent_count,
- { "Dir Entry Count", "pvfs.dirent_count", FT_UINT64, BASE_DEC,
- NULL, 0, "Directory Entry Count", HFILL }},
-
- { &hf_pvfs_directory_version,
- { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
- NULL, 0, "Directory Version", HFILL }},
-
- { &hf_pvfs_path,
- { "Path", "pvfs.path", FT_STRING, BASE_DEC,
- NULL, 0, "Path", HFILL }},
-
- { &hf_pvfs_total_completed,
- { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
- NULL, 0, "Bytes Completed", HFILL }},
-
- { &hf_pvfs_io_dist,
- { "Name", "pvfs.distribution.name", FT_STRING, BASE_DEC,
- NULL, 0, "Distribution Name", HFILL }},
-
- { &hf_pvfs_aggregate_size,
- { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
- NULL, 0, "Aggregate Size", HFILL }},
-
- { &hf_pvfs_io_type,
- { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_io_type), 0, "I/O Type", HFILL }},
-
- { &hf_pvfs_flowproto_type,
- { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_flowproto_type), 0, "Flow Protocol Type", HFILL }},
-
- { &hf_pvfs_server_param,
- { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
- VALS(names_pvfs_server_param), 0, "Server Parameter", HFILL }},
-
- { &hf_pvfs_prev_value,
- { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
- NULL, 0, "Previous Value", HFILL }},
-
- { &hf_pvfs_ram_free_bytes,
- { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
- NULL, 0, "RAM Free Bytes", HFILL }},
-
- { &hf_pvfs_bytes_available,
- { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
- NULL, 0, "Bytes Available", HFILL }},
-
- { &hf_pvfs_bytes_total,
- { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
- NULL, 0, "Bytes Total", HFILL }},
-
- { &hf_pvfs_ram_bytes_total,
- { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
- NULL, 0, "RAM Bytes Total", HFILL }},
-
- { &hf_pvfs_ram_bytes_free,
- { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
- NULL, 0, "RAM Bytes Free", HFILL }},
-
- { &hf_pvfs_load_average_1s,
- { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
- NULL, 0, "Load Average (1s)", HFILL }},
-
- { &hf_pvfs_load_average_5s,
- { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
- NULL, 0, "Load Average (5s)", HFILL }},
-
- { &hf_pvfs_load_average_15s,
- { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
- NULL, 0, "Load Average (15s)", HFILL }},
-
- { &hf_pvfs_uptime_seconds,
- { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
- NULL, 0, "Uptime (seconds)", HFILL }},
-
- { &hf_pvfs_handles_available,
- { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
- NULL, 0, "Handles Available", HFILL }},
-
- { &hf_pvfs_handles_total,
- { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
- NULL, 0, "Total Handles", HFILL }},
-
- /*
- * This is used when the field returns 64-bits but we're only interested
- * in the lower 32-bit bits.
- */
- { &hf_pvfs_unused,
- { "Unused", "", FT_UINT32, BASE_DEC,
- NULL, 0, "Unused", HFILL }},
-
- { &hf_pvfs_context_id,
- { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
- NULL, 0, "Context ID", HFILL }},
-
- { &hf_pvfs_offset,
- { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
- NULL, 0, "Offset", HFILL }},
-
- { &hf_pvfs_stride,
- { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
- NULL, 0, "Stride", HFILL }},
-
- { &hf_pvfs_ub,
- { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
- NULL, 0, "ub", HFILL }},
-
- { &hf_pvfs_lb,
- { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
- NULL, 0, "lb", HFILL }},
-
- { &hf_pvfs_end_time_ms,
- { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
- NULL, 0, "end_time_ms", HFILL }},
-
- { &hf_pvfs_cur_time_ms,
- { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
- NULL, 0, "cur_time_ms", HFILL }},
-
- { &hf_pvfs_start_time_ms,
- { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
- NULL, 0, "start_time_ms", HFILL }},
-
- { &hf_pvfs_bytes_written,
- { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
- NULL, 0, "bytes_written", HFILL }},
-
- { &hf_pvfs_bytes_read,
- { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
- NULL, 0, "bytes_read", HFILL }},
-
- { &hf_pvfs_metadata_write,
- { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
- NULL, 0, "metadata_write", HFILL }},
-
- { &hf_pvfs_metadata_read,
- { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
- NULL, 0, "metadata_read", HFILL }},
-
- { &hf_pvfs_b_size,
- { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
- BASE_DEC, NULL, 0, "Size of bstream", HFILL }},
-
- { &hf_pvfs_k_size,
- { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
- BASE_DEC, NULL, 0, "Number of keyvals", HFILL }},
-
- { &hf_pvfs_id_gen_t,
- { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
- NULL, 0, "id_gen_t", HFILL }},
-
- { &hf_pvfs_attribute_key,
- { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_DEC,
- NULL, 0, "Attribute key", HFILL }},
-
- { &hf_pvfs_attribute_value,
- { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_DEC,
- NULL, 0, "Attribute value", HFILL }},
-
- { &hf_pvfs_strip_size,
- { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
- NULL, 0, "Strip size (bytes)", HFILL }},
-
- /* TODO: need description */
- { &hf_pvfs_ereg,
- { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
- NULL, 0, "ereg", HFILL }},
-
- /* TODO: need description */
- { &hf_pvfs_sreg,
- { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
- NULL, 0, "sreg", HFILL }},
-
- { &hf_pvfs_num_eregs,
- { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
- NULL, 0, "Number of eregs", HFILL }},
-
- { &hf_pvfs_num_blocks,
- { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
- NULL, 0, "Number of blocks", HFILL }},
-
- { &hf_pvfs_num_contig_chunks,
- { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
- BASE_DEC, NULL, 0, "Number of contig_chunks", HFILL }},
-
- { &hf_pvfs_server_nr,
- { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
- NULL, 0, "Server #", HFILL }},
-
- { &hf_pvfs_server_count,
- { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
- NULL, 0, "Number of servers", HFILL }},
-
- { &hf_pvfs_fh_length,
- { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
- NULL, 0, "file handle length", HFILL }},
-
- { &hf_pvfs_fh_hash,
- { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
- NULL, 0, "file handle hash", HFILL }},
- };
-
- /* Setup protocol subtree array */
- static gint *ett[] = {
- &ett_pvfs,
- &ett_pvfs_hdr,
- &ett_pvfs_credentials,
- &ett_pvfs_server_config,
- &ett_pvfs_server_config_branch,
- &ett_pvfs_attrmask,
- &ett_pvfs_time,
- &ett_pvfs_extent_array_tree,
- &ett_pvfs_extent_item,
- &ett_pvfs_string,
- &ett_pvfs_attr_tree,
- &ett_pvfs_distribution,
- &ett_pvfs_mgmt_perf_stat,
- &ett_pvfs_mgmt_dspace_info,
- &ett_pvfs_attr,
- &ett_pvfs_fh
- };
- module_t *pvfs_module;
-
- /* Register the protocol name and description */
- proto_pvfs = proto_register_protocol("Parallel Virtual File System",
- "PVFS", "pvfs");
-
- /*
- * Required function calls to register the header fields and
- * subtrees used
- */
-
- proto_register_field_array(proto_pvfs, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
-
- register_init_routine(pvfs2_io_tracking_init);
-
- pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
- prefs_register_bool_preference(pvfs_module, "desegment",
- "Reassemble PVFS messages spanning multiple TCP segments",
- "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
- "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
- &pvfs_desegment);
-}
-
-void
-proto_reg_handoff_pvfs(void)
-{
- dissector_handle_t pvfs_handle;
-
- pvfs_handle = new_create_dissector_handle(dissect_pvfs_heur, proto_pvfs);
- dissector_add("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
-
- heur_dissector_add("tcp", dissect_pvfs_heur, proto_pvfs);
-}
-
+/* packet-pvfs.c
+ * Routines for pvfs2 packet dissection
+ * By Mike Frisch <mfrisch@platform.com>
+ * Joint and Several Copyright 2005, Mike Frisch and Platform Computing Inc.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from packet-smb.c and others
+ *
+ * TODO
+ *
+ * - Add filename snooping (match file handles with file names),
+ * similar to how packet-rpc.c/packet-nfs.c implements it
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/emem.h>
+#include <epan/strutil.h>
+#include <epan/prefs.h>
+#include "packet-tcp.h"
+
+#define TCP_PORT_PVFS2 3334
+
+#define PVFS2_FH_LENGTH 8
+
+/* Header incl. magic number, mode, tag, size */
+#define BMI_HEADER_SIZE 24
+
+/* desegmentation of PVFS over TCP */
+static gboolean pvfs_desegment = TRUE;
+
+/* Forward declaration we need below */
+void proto_reg_handoff_pvfs(void);
+
+/* Initialize the protocol and registered fields */
+static int proto_pvfs = -1;
+static int hf_pvfs_magic_nr = -1;
+static int hf_pvfs_mode = -1;
+static int hf_pvfs_tag = -1;
+static int hf_pvfs_size = -1;
+static int hf_pvfs_release_number = -1;
+static int hf_pvfs_encoding = -1;
+static int hf_pvfs_server_op = -1;
+static int hf_pvfs_handle = -1;
+static int hf_pvfs_fs_id = -1;
+static int hf_pvfs_attrmask = -1;
+static int hf_pvfs_attr = -1;
+static int hf_pvfs_ds_type = -1;
+static int hf_pvfs_error = -1;
+static int hf_pvfs_atime = -1;
+static int hf_pvfs_atime_sec = -1;
+static int hf_pvfs_atime_nsec = -1;
+static int hf_pvfs_mtime = -1;
+static int hf_pvfs_mtime_sec = -1;
+static int hf_pvfs_mtime_nsec = -1;
+static int hf_pvfs_ctime = -1;
+static int hf_pvfs_ctime_sec = -1;
+static int hf_pvfs_ctime_nsec = -1;
+static int hf_pvfs_parent_atime = -1;
+static int hf_pvfs_parent_atime_sec = -1;
+static int hf_pvfs_parent_atime_nsec = -1;
+static int hf_pvfs_parent_mtime = -1;
+static int hf_pvfs_parent_mtime_sec = -1;
+static int hf_pvfs_parent_mtime_nsec = -1;
+static int hf_pvfs_parent_ctime = -1;
+static int hf_pvfs_parent_ctime_sec = -1;
+static int hf_pvfs_parent_ctime_nsec = -1;
+static int hf_pvfs_dirent_count = -1;
+static int hf_pvfs_directory_version = -1;
+static int hf_pvfs_path = -1;
+static int hf_pvfs_total_completed = -1;
+static int hf_pvfs_io_dist = -1;
+static int hf_pvfs_aggregate_size = -1;
+static int hf_pvfs_io_type = -1;
+static int hf_pvfs_flowproto_type = -1;
+static int hf_pvfs_server_param = -1;
+static int hf_pvfs_prev_value = -1;
+static int hf_pvfs_ram_free_bytes = -1;
+static int hf_pvfs_bytes_available = -1;
+static int hf_pvfs_bytes_total = -1;
+static int hf_pvfs_ram_bytes_total = -1;
+static int hf_pvfs_ram_bytes_free = -1;
+static int hf_pvfs_load_average_1s = -1;
+static int hf_pvfs_load_average_5s = -1;
+static int hf_pvfs_load_average_15s = -1;
+static int hf_pvfs_uptime_seconds = -1;
+static int hf_pvfs_handles_available = -1;
+static int hf_pvfs_handles_total = -1;
+static int hf_pvfs_unused = -1;
+static int hf_pvfs_context_id = -1;
+static int hf_pvfs_offset = -1;
+static int hf_pvfs_stride = -1;
+static int hf_pvfs_lb = -1;
+static int hf_pvfs_ub = -1;
+static int hf_pvfs_end_time_ms = -1;
+static int hf_pvfs_cur_time_ms = -1;
+static int hf_pvfs_start_time_ms = -1;
+static int hf_pvfs_bytes_written = -1;
+static int hf_pvfs_bytes_read = -1;
+static int hf_pvfs_metadata_write = -1;
+static int hf_pvfs_metadata_read = -1;
+static int hf_pvfs_b_size = -1;
+static int hf_pvfs_k_size = -1;
+static int hf_pvfs_id_gen_t = -1;
+static int hf_pvfs_attribute_key = -1;
+static int hf_pvfs_attribute_value = -1;
+static int hf_pvfs_strip_size = -1;
+static int hf_pvfs_ereg = -1;
+static int hf_pvfs_sreg = -1;
+static int hf_pvfs_num_eregs = -1;
+static int hf_pvfs_num_blocks = -1;
+static int hf_pvfs_num_contig_chunks = -1;
+static int hf_pvfs_server_nr = -1;
+static int hf_pvfs_server_count = -1;
+static int hf_pvfs_fh_length = -1;
+static int hf_pvfs_fh_hash = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_pvfs = -1;
+static gint ett_pvfs_hdr = -1;
+static gint ett_pvfs_credentials = -1;
+static gint ett_pvfs_server_config = -1;
+static gint ett_pvfs_server_config_branch = -1;
+static gint ett_pvfs_attrmask = -1;
+static gint ett_pvfs_time = -1;
+static gint ett_pvfs_extent_array_tree = -1;
+static gint ett_pvfs_extent_item = -1;
+static gint ett_pvfs_string = -1;
+static gint ett_pvfs_attr_tree = -1;
+static gint ett_pvfs_distribution = -1;
+static gint ett_pvfs_mgmt_perf_stat = -1;
+static gint ett_pvfs_mgmt_dspace_info = -1;
+static gint ett_pvfs_attr = -1;
+static gint ett_pvfs_fh = -1;
+
+#define BMI_MAGIC_NR 51903
+
+static const value_string names_pvfs_mode[] =
+{
+#define TCP_MODE_IMMED 1
+ { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
+#define TCP_MODE_UNEXP 2
+ { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
+#define TCP_MODE_EAGER 4
+ { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
+#define TCP_MODE_REND 8
+ { TCP_MODE_REND, "TCP_MODE_REND" },
+ { 0, NULL }
+};
+
+static const value_string names_pvfs_encoding[] =
+{
+#define PVFS_ENCODING_DIRECT 1
+ { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
+#define PVFS_ENCODING_LE_BFIELD 2
+ { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
+#define PVFS_ENCODING_XDR 3
+ { PVFS_ENCODING_XDR, "ENCODING_XDR" },
+ { 0, NULL }
+};
+
+static const value_string names_pvfs_io_type[] =
+{
+#define PVFS_IO_READ 1
+ { PVFS_IO_READ, "PVFS_IO_READ" },
+#define PVFS_IO_WRITE 2
+ { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
+ { 0, NULL }
+};
+
+static const value_string names_pvfs_flowproto_type[] =
+{
+#define FLOWPROTO_DUMP_OFFSETS 1
+ { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
+#define FLOWPROTO_BMI_CACHE 2
+ { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
+#define FLOWPROTO_MULTIQUEUE 3
+ { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
+ { 0, NULL }
+};
+
+static const value_string names_pvfs_server_param[] =
+{
+#define PVFS_SERV_PARAM_INVALID 0
+ { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
+#define PVFS_SERV_PARAM_GOSSIP_MASK 1
+ { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
+#define PVFS_SERV_PARAM_FSID_CHECK 2
+ { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
+#define PVFS_SERV_PARAM_ROOT_CHECK 3
+ { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
+#define PVFS_SERV_PARAM_MODE 4
+ { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
+#define PVFS_SERV_PARAM_EVENT_ON 5
+ { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
+#define PVFS_SERV_PARAM_EVENT_MASKS 6
+ { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
+ { 0, NULL }
+};
+
+static const value_string names_pvfs_server_mode[] =
+{
+#define PVFS_SERVER_NORMAL_MODE 1
+ { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
+#define PVFS_SERVER_ADMIN_MODE 2
+ { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
+ { 0, NULL }
+};
+
+/* Forward declaration */
+static gboolean
+dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean dissect_other_as_continuation);
+
+
+static void dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_pvfs_common(tvb, pinfo, tree, FALSE);
+
+}
+
+static guint get_pvfs_pdu_len(tvbuff_t *tvb, int offset)
+{
+ guint32 plen;
+
+ /*
+ * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
+ */
+ plen = tvb_get_letohl(tvb, offset + 16);
+
+ return plen+24;
+}
+
+static int
+dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint32 magic_nr, mode;
+ guint64 size;
+
+ /* verify that this is indeed PVFS and that it looks sane */
+ if(tvb_length_remaining(tvb,0)<24){
+ /* too few bytes remaining to verify the header */
+ return 0;
+ }
+
+ /* validate the magic number */
+ magic_nr = tvb_get_letohl(tvb, 0);
+ if(magic_nr!=BMI_MAGIC_NR){
+ return 0;
+ }
+
+ /* Validate the TCP message mode (32-bit) */
+ mode = tvb_get_letohl(tvb, 4);
+ switch(mode){
+ case TCP_MODE_IMMED:
+ case TCP_MODE_UNEXP:
+ case TCP_MODE_EAGER:
+ case TCP_MODE_REND:
+ break;
+ default:
+ /* invalid mode, not a PVFS packet */
+ return 0;
+ }
+
+ /* validate the size : assume size must be >0 and less than 1000000 */
+ size=tvb_get_letohl(tvb, 20);
+ size<<=32;
+ size|=tvb_get_letohl(tvb, 16);
+ if((size>1000000)||(size==0)){
+ return 0;
+ }
+
+ tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
+ dissect_pvfs_pdu);
+
+ return tvb_length(tvb);
+}
+
+static const value_string names_pvfs_server_op[] =
+{
+#define PVFS_SERV_INVALID 0
+ { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
+#define PVFS_SERV_CREATE 1
+ { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
+#define PVFS_SERV_REMOVE 2
+ { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
+#define PVFS_SERV_IO 3
+ { PVFS_SERV_IO, "PVFS_SERV_IO" },
+#define PVFS_SERV_GETATTR 4
+ { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
+#define PVFS_SERV_SETATTR 5
+ { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
+#define PVFS_SERV_LOOKUP_PATH 6
+ { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
+#define PVFS_SERV_CRDIRENT 7
+ { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
+#define PVFS_SERV_RMDIRENT 8
+ { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
+#define PVFS_SERV_CHDIRENT 9
+ { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
+#define PVFS_SERV_TRUNCATE 10
+ { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
+#define PVFS_SERV_MKDIR 11
+ { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
+#define PVFS_SERV_READDIR 12
+ { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
+#define PVFS_SERV_GETCONFIG 13
+ { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
+#define PVFS_SERV_WRITE_COMPLETION 14
+ { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
+#define PVFS_SERV_FLUSH 15
+ { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
+#define PVFS_SERV_MGMT_SETPARAM 16
+ { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
+#define PVFS_SERV_MGMT_NOOP 17
+ { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
+#define PVFS_SERV_STATFS 18
+ { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
+#define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
+ { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
+#define PVFS_SERV_MGMT_PERF_MON 20
+ { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
+#define PVFS_SERV_MGMT_ITERATE_HANDLES 21
+ { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
+#define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
+ { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
+#define PVFS_SERV_MGMT_EVENT_MON 23
+ { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
+#define PVFS_SERV_MGMT_REMOVE_OBJECT 24
+ { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
+#define PVFS_SERV_MGMT_REMOVE_DIRENT 25
+ { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
+#define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
+ { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
+#define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
+ { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
+#define PVFS_SERV_PROTO_ERROR 28
+ { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
+#define PVFS_SERV_GETEATTR 29
+ { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
+#define PVFS_SERV_SETEATTR 30
+ { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
+#define PVFS_SERV_DELEATTR 31
+ { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
+ { 0, NULL }
+};
+
+/* special bits used to differentiate PVFS error codes from system
+ * * errno values
+ * */
+#define PVFS_ERROR_BIT (1 << 30)
+
+/* a shorthand to make the error code definitions more readable */
+#define E(num) (num|PVFS_ERROR_BIT)
+
+static const value_string names_pvfs_error[] = {
+ { 0, "Success" },
+#define PVFS_EPERM E(1) /* Operation not permitted */
+ { PVFS_EPERM, "PVFS_EPERM" },
+#define PVFS_ENOENT E(2) /* No such file or directory */
+ { PVFS_ENOENT, "PVFS_ENOENT" },
+#define PVFS_EINTR E(3) /* Interrupted system call */
+ { PVFS_EINTR, "PVFS_EINTR" },
+#define PVFS_EIO E(4) /* I/O error */
+ { PVFS_EIO, "PVFS_EIO" },
+#define PVFS_ENXIO E(5) /* No such device or address */
+ { PVFS_ENXIO, "PVFS_ENXIO" },
+#define PVFS_EBADF E(6) /* Bad file number */
+ { PVFS_EBADF, "PVFS_EBADF" },
+#define PVFS_EAGAIN E(7) /* Try again */
+ { PVFS_EAGAIN, "PVFS_EAGAIN" },
+#define PVFS_ENOMEM E(8) /* Out of memory */
+ { PVFS_ENOMEM, "PVFS_ENOMEM" },
+#define PVFS_EFAULT E(9) /* Bad address */
+ { PVFS_EFAULT, "PVFS_EFAULT" },
+#define PVFS_EBUSY E(10) /* Device or resource busy */
+ { PVFS_EBUSY, "PVFS_EBUSY" },
+#define PVFS_EEXIST E(11) /* File exists */
+ { PVFS_EEXIST, "PVFS_EEXIST" },
+#define PVFS_ENODEV E(12) /* No such device */
+ { PVFS_ENODEV, "PVFS_ENODEV" },
+#define PVFS_ENOTDIR E(13) /* Not a directory */
+ { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
+#define PVFS_EISDIR E(14) /* Is a directory */
+ { PVFS_EISDIR, "PVFS_EISDIR" },
+#define PVFS_EINVAL E(15) /* Invalid argument */
+ { PVFS_EINVAL, "PVFS_EINVAL" },
+#define PVFS_EMFILE E(16) /* Too many open files */
+ { PVFS_EMFILE, "PVFS_EMFILE" },
+#define PVFS_EFBIG E(17) /* File too large */
+ { PVFS_EFBIG, "PVFS_EFBIG" },
+#define PVFS_ENOSPC E(18) /* No space left on device */
+ { PVFS_ENOSPC, "PVFS_ENOSPC" },
+#define PVFS_EROFS E(19) /* Read-only file system */
+ { PVFS_EROFS, "PVFS_EROFS" },
+#define PVFS_EMLINK E(20) /* Too many links */
+ { PVFS_EMLINK, "PVFS_EMLINK" },
+#define PVFS_EPIPE E(21) /* Broken pipe */
+ { PVFS_EPIPE, "PVFS_EPIPE" },
+#define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
+ { PVFS_EDEADLK, "PVFS_EDEADLK" },
+#define PVFS_ENAMETOOLONG E(23) /* File name too long */
+ { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
+#define PVFS_ENOLCK E(24) /* No record locks available */
+ { PVFS_ENOLCK, "PVFS_ENOLCK" },
+#define PVFS_ENOSYS E(25) /* Function not implemented */
+ { PVFS_ENOSYS, "PVFS_ENOSYS" },
+#define PVFS_ENOTEMPTY E(26) /* Directory not empty */
+ { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
+#define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
+ { PVFS_ELOOP, "PVFS_ELOOP" },
+#define PVFS_EWOULDBLOCK E(28) /* Operation would block */
+ { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
+#define PVFS_ENOMSG E(29) /* No message of desired type */
+ { PVFS_ENOMSG, "PVFS_ENOMSG" },
+#define PVFS_EUNATCH E(30) /* Protocol driver not attached */
+ { PVFS_EUNATCH, "PVFS_EUNATCH" },
+#define PVFS_EBADR E(31) /* Invalid request descriptor */
+ { PVFS_EBADR, "PVFS_EBADR" },
+#define PVFS_EDEADLOCK E(32)
+ { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
+#define PVFS_ENODATA E(33) /* No data available */
+ { PVFS_ENODATA, "PVFS_ENODATA" },
+#define PVFS_ETIME E(34) /* Timer expired */
+ { PVFS_ETIME, "PVFS_ETIME" },
+#define PVFS_ENONET E(35) /* Machine is not on the network */
+ { PVFS_ENONET, "PVFS_ENONET" },
+#define PVFS_EREMOTE E(36) /* Object is remote */
+ { PVFS_EREMOTE, "PVFS_EREMOTE" },
+#define PVFS_ECOMM E(37) /* Communication error on send */
+ { PVFS_ECOMM, "PVFS_ECOMM" },
+#define PVFS_EPROTO E(38) /* Protocol error */
+ { PVFS_EPROTO, "PVFS_EPROTO" },
+#define PVFS_EBADMSG E(39) /* Not a data message */
+ { PVFS_EBADMSG, "PVFS_EBADMSG" },
+#define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
+ { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
+#define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
+ { PVFS_ERESTART, "PVFS_ERESTART" },
+#define PVFS_EMSGSIZE E(42) /* Message too long */
+ { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
+#define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
+ { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
+#define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
+ { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
+#define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
+ { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
+#define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
+ { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
+#define PVFS_EADDRINUSE E(47) /* Address already in use */
+ { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
+#define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
+ { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
+#define PVFS_ENETDOWN E(49) /* Network is down */
+ { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
+#define PVFS_ENETUNREACH E(50) /* Network is unreachable */
+ { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
+#define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
+ { PVFS_ENETRESET, "PVFS_ENETRESET" },
+#define PVFS_ENOBUFS E(52) /* No buffer space available */
+ { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
+#define PVFS_ETIMEDOUT E(53) /* Connection timed out */
+ { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
+#define PVFS_ECONNREFUSED E(54) /* Connection refused */
+ { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
+#define PVFS_EHOSTDOWN E(55) /* Host is down */
+ { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
+#define PVFS_EHOSTUNREACH E(56) /* No route to host */
+ { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
+#define PVFS_EALREADY E(57) /* Operation already in progress */
+ { PVFS_EALREADY, "PVFS_EALREADY" },
+#define PVFS_EACCES E(58) /* Operation already in progress */
+ { PVFS_EACCES, "PVFS_EACCES" },
+ { 0, NULL }
+};
+
+static int
+dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ gint32 err;
+ const char *errmsg = NULL;
+
+ err = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
+ offset += 4;
+
+ if ((err != 0) && check_col(pinfo->cinfo, COL_INFO))
+ {
+ errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
+ }
+
+ return offset;
+}
+
+static int
+dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
+ int offset)
+{
+ proto_item *item = NULL;
+ proto_tree *hcred_tree = NULL;
+ guint32 uid = 0, gid = 0;
+
+ uid = tvb_get_letohl(tvb, offset);
+ gid = tvb_get_letohl(tvb, offset + 4);
+
+ if (parent_tree)
+ {
+ item = proto_tree_add_text(parent_tree, tvb, offset, 8,
+ "Credentials (UID: %d, GID: %d)", uid, gid);
+
+ if (item)
+ hcred_tree = proto_item_add_subtree(item, ett_pvfs_credentials);
+ }
+
+ /* UID */
+ proto_tree_add_text(hcred_tree, tvb, offset, 4, "UID: %d", uid);
+ offset += 4;
+
+ /* GID */
+ proto_tree_add_text(hcred_tree, tvb, offset, 4, "GID: %d", gid);
+ offset += 4;
+
+ return offset;
+}
+
+static const value_string names_pvfs_attr[] =
+{
+#define PVFS_ATTR_COMMON_UID (1 << 0)
+#define PVFS_ATTR_BIT_COMMON_UID 0
+ { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
+
+#define PVFS_ATTR_COMMON_GID (1 << 1)
+#define PVFS_ATTR_BIT_COMMON_GID 1
+ { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
+
+#define PVFS_ATTR_COMMON_PERM (1 << 2)
+#define PVFS_ATTR_BIT_COMMON_PERM 2
+ { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
+
+#define PVFS_ATTR_COMMON_ATIME (1 << 3)
+#define PVFS_ATTR_BIT_COMMON_ATIME 3
+ { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
+
+#define PVFS_ATTR_COMMON_CTIME (1 << 4)
+#define PVFS_ATTR_BIT_COMMON_CTIME 4
+ { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
+
+#define PVFS_ATTR_COMMON_MTIME (1 << 5)
+#define PVFS_ATTR_BIT_COMMON_MTIME 5
+ { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
+
+#define PVFS_ATTR_COMMON_TYPE (1 << 6)
+#define PVFS_ATTR_BIT_COMMON_TYPE 6
+ { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
+
+#if 0
+#define PVFS_ATTR_COMMON_ALL \
+ (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
+ PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
+ PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
+ PVFS_ATTR_COMMON_TYPE)
+#endif
+
+/* internal attribute masks for metadata objects */
+#define PVFS_ATTR_META_DIST (1 << 10)
+#define PVFS_ATTR_BIT_META_DIST 10
+ { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
+
+#define PVFS_ATTR_META_DFILES (1 << 11)
+#define PVFS_ATTR_BIT_META_DFILES 11
+ { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
+
+#if 0
+#define PVFS_ATTR_META_ALL \
+ (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
+#endif
+
+/* internal attribute masks for datafile objects */
+#define PVFS_ATTR_DATA_SIZE (1 << 15)
+#define PVFS_ATTR_BIT_DATA_SIZE 15
+ { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
+
+#if 0
+#define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
+#endif
+
+/* internal attribute masks for symlink objects */
+#define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
+#define PVFS_ATTR_BIT_SYMLINK_TARGET 18
+ { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
+
+#if 0
+#define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
+#endif
+
+/* internal attribute masks for directory objects */
+#define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
+#define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
+ { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
+
+#if 0
+#define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
+#endif
+
+/* attribute masks used by system interface callers */
+#define PVFS_ATTR_SYS_SIZE (1 << 20)
+#define PVFS_ATTR_BIT_SYS_SIZE 20
+ { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
+
+#define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
+#define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
+ { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
+
+#define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
+#define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
+ { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
+
+#define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
+#define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
+ { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
+
+#if 0
+#define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
+#define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
+#define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
+#define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
+#define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
+#define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
+#define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
+#endif
+ { 0, NULL }
+};
+
+#if 0
+#define PVFS_ATTR_SYS_ALL \
+ (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
+ PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
+ PVFS_ATTR_SYS_DIRENT_COUNT)
+
+#define PVFS_ATTR_SYS_ALL_NOSIZE \
+ (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
+ PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
+
+#define PVFS_ATTR_SYS_ALL_SETABLE \
+ (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
+#endif
+
+
+static int
+dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
+ guint32 *pattrmask)
+{
+ guint32 attrmask = 0, i = 0;
+ proto_item *attritem = NULL;
+ proto_tree *attrtree = NULL;
+
+ attrmask = tvb_get_letohl(tvb, offset);
+
+ attritem = proto_tree_add_text(tree, tvb, offset, 4,
+ "Attribute Mask: %d", attrmask);
+
+ if (attritem)
+ attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
+
+ for (i = 0; i < 32; i++)
+ {
+ if (attrmask & (1 << i))
+ proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
+ }
+
+ offset += 4;
+
+ if (pattrmask)
+ *pattrmask = attrmask;
+
+ return offset;
+}
+
+static const value_string names_pvfs_ds_type[] = {
+#define PVFS_TYPE_NONE 0
+ { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
+#define PVFS_TYPE_METAFILE (1 << 0)
+ { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
+#define PVFS_TYPE_DATAFILE (1 << 1)
+ { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
+#define PVFS_TYPE_DIRECTORY (1 << 2)
+ { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
+#define PVFS_TYPE_SYMLINK (1 << 3)
+ { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
+#define PVFS_TYPE_DIRDATA (1 << 4)
+ { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
+ { 0, NULL }
+};
+
+static int
+dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
+ int *pds_type)
+{
+ guint32 ds_type = 0;
+
+ ds_type = tvb_get_letohl(tvb, offset);
+
+ if (tree)
+ proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
+
+ offset += 4;
+
+ if (pds_type)
+ *pds_type = ds_type;
+
+ return offset;
+}
+
+#define roundup4(x) (((x) + 3) & ~3)
+#define roundup8(x) (((x) + 7) & ~7)
+
+static int
+dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
+ proto_tree *tree,
+ packet_info *pinfo _U_,
+ int hfindex,
+ gboolean fixed_length, guint32 length,
+ gboolean string_data, char **string_buffer_ret)
+{
+ int data_offset;
+ proto_item *string_item = NULL;
+ proto_tree *string_tree = NULL;
+
+ guint32 string_length;
+ guint32 string_length_full;
+ guint32 string_length_packet;
+ guint32 string_length_captured;
+ guint32 string_length_copy;
+
+ int fill_truncated;
+ guint32 fill_length;
+ guint32 fill_length_packet;
+ guint32 fill_length_captured;
+ guint32 fill_length_copy;
+
+ int exception = 0;
+
+ char *string_buffer = NULL;
+ char *string_buffer_print = NULL;
+
+ if (fixed_length) {
+ string_length = length;
+ data_offset = offset;
+ } else {
+ string_length = tvb_get_letohl(tvb,offset+0);
+ data_offset = offset + 4;
+
+ /*
+ * Variable-length strings include NULL terminator on-the-wire but
+ * NULL terminator is not included in string length.
+ */
+
+ if (string_data)
+ string_length += 1;
+ }
+
+ string_length_captured = tvb_length_remaining(tvb, data_offset);
+ string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
+
+ /*
+ * Strangeness... the protocol basically says that the length plus
+ * the string must be padded out to an 8-byte boundary.
+ */
+
+ if (!string_data)
+ string_length_full = roundup4(string_length);
+ else
+ string_length_full = roundup8(4 + string_length);
+
+ if (string_length_captured < string_length) {
+ /* truncated string */
+ string_length_copy = string_length_captured;
+ fill_truncated = 2;
+ fill_length = 0;
+ fill_length_copy = 0;
+
+ if (string_length_packet < string_length)
+ exception = ReportedBoundsError;
+ else
+ exception = BoundsError;
+ }
+ else {
+ /* full string data */
+ string_length_copy = string_length;
+
+ if (!string_data)
+ fill_length = string_length_full - string_length;
+ else
+ fill_length = string_length_full - string_length - 4;
+
+ fill_length_captured = tvb_length_remaining(tvb,
+ data_offset + string_length);
+ fill_length_packet = tvb_reported_length_remaining(tvb,
+ data_offset + string_length);
+
+ if (fill_length_captured < fill_length) {
+ /* truncated fill bytes */
+ fill_length_copy = fill_length_packet;
+ fill_truncated = 1;
+ if (fill_length_packet < fill_length)
+ exception = ReportedBoundsError;
+ else
+ exception = BoundsError;
+ }
+ else {
+ /* full fill bytes */
+ fill_length_copy = fill_length;
+ fill_truncated = 0;
+ }
+ }
+
+ if (string_data) {
+ char *tmpstr;
+
+ tmpstr = (char *) tvb_get_ephemeral_string(tvb, data_offset,
+ string_length_copy);
+
+ string_buffer = memcpy(ep_alloc(string_length_copy+1), tmpstr, string_length_copy);
+ } else {
+ string_buffer = (char *) tvb_memcpy(tvb,
+ ep_alloc(string_length_copy+1), data_offset, string_length_copy);
+ }
+
+ string_buffer[string_length_copy] = '\0';
+
+ /* calculate a nice printable string */
+ if (string_length) {
+ if (string_length != string_length_copy) {
+ if (string_data) {
+ char *formatted;
+ guint16 string_buffer_size = 0;
+
+ formatted = format_text((guint8 *)string_buffer,
+ strlen(string_buffer));
+
+ string_buffer_size = strlen(formatted) + 12 + 1;
+
+ /* alloc maximum data area */
+ string_buffer_print = (char*) ep_alloc(string_buffer_size);
+ /* copy over the data */
+ g_snprintf(string_buffer_print, string_buffer_size - 1,
+ "%s<TRUNCATED>", formatted);
+ /* append <TRUNCATED> */
+ /* This way, we get the TRUNCATED even
+ in the case of totally wrong packets,
+ where \0 are inside the string.
+ TRUNCATED will appear at the
+ first \0 or at the end (where we
+ put the securing \0).
+ */
+ } else {
+ string_buffer_print="<DATA><TRUNCATED>";
+ }
+ } else {
+ if (string_data) {
+ string_buffer_print = (char *)
+ ep_strdup(format_text((guint8 *) string_buffer,
+ strlen(string_buffer)));
+ } else {
+ string_buffer_print="<DATA>";
+ }
+ }
+ } else {
+ string_buffer_print="<EMPTY>";
+ }
+
+ if (tree) {
+ string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
+ "%s: %s", proto_registrar_get_name(hfindex),
+ string_buffer_print);
+
+ if (string_item)
+ string_tree = proto_item_add_subtree(string_item,
+ ett_pvfs_string);
+ }
+ if (!fixed_length) {
+ if (string_tree)
+ proto_tree_add_text(string_tree, tvb,offset+0,4,
+ "length: %u (excl. NULL terminator)", string_length - 1);
+ offset += 4;
+ }
+
+ if (string_tree) {
+ if (string_data) {
+ proto_tree_add_string_format(string_tree,
+ hfindex, tvb, offset, string_length_copy,
+ string_buffer,
+ "contents: %s", string_buffer_print);
+ } else {
+ proto_tree_add_bytes_format(string_tree,
+ hfindex, tvb, offset, string_length_copy,
+ (guint8 *) string_buffer,
+ "contents: %s", string_buffer_print);
+ }
+ }
+
+ offset += string_length_copy;
+
+ if (fill_length) {
+ if (string_tree) {
+ if (fill_truncated) {
+ proto_tree_add_text(string_tree, tvb,
+ offset,fill_length_copy,
+ "fill bytes: opaque data<TRUNCATED>");
+ }
+ else {
+ proto_tree_add_text(string_tree, tvb,
+ offset,fill_length_copy,
+ "fill bytes: opaque data");
+ }
+ }
+ offset += fill_length_copy;
+ }
+
+ if (string_item)
+ proto_item_set_end(string_item, tvb, offset);
+
+ if (string_buffer_ret != NULL)
+ *string_buffer_ret = string_buffer_print;
+
+ /*
+ * If the data was truncated, throw the appropriate exception,
+ * so that dissection stops and the frame is properly marked.
+ */
+ if (exception != 0)
+ THROW(exception);
+
+ return offset;
+}
+
+static int
+dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
+ int offset, char **string_buffer_ret)
+{
+ return dissect_pvfs_opaque_data(tvb, offset, tree, NULL, hfindex,
+ FALSE, 0, TRUE, string_buffer_ret);
+}
+
+static void
+dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+ guint sublen;
+ guint bytes_left;
+ gboolean first_line;
+
+ bytes_left = PVFS2_FH_LENGTH;
+ first_line = TRUE;
+ while (bytes_left != 0) {
+ sublen = 16;
+ if (sublen > bytes_left)
+ sublen = bytes_left;
+ proto_tree_add_text(tree, tvb, offset, sublen,
+ "%s%s",
+ first_line ? "data: " :
+ " ",
+ tvb_bytes_to_str(tvb,offset,sublen));
+ bytes_left -= sublen;
+ offset += sublen;
+ first_line = FALSE;
+ }
+}
+
+static void
+dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 *hash)
+{
+ guint32 fhhash;
+ guint32 i;
+
+ /* Not all bytes there. Any attempt to deduce the type would be
+ senseless. */
+ if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
+ goto type_ready;
+
+ /* create a semiunique hash value for the filehandle */
+ for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
+ guint32 val;
+ val = tvb_get_ntohl(tvb, offset+i);
+ fhhash ^= val;
+ fhhash += val;
+ }
+
+ proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
+ fhhash);
+
+ if (hash)
+ *hash = fhhash;
+
+ /* TODO: add file name snooping code here */
+
+type_ready:
+ dissect_fhandle_data_unknown(tvb, offset, tree);
+}
+
+static int
+dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, const char *name, guint32 *hash)
+{
+ proto_item* fitem = NULL;
+ proto_tree* ftree = NULL;
+
+ if (tree)
+ {
+ fitem = proto_tree_add_text(tree, tvb, offset, PVFS2_FH_LENGTH,
+ "%s", name);
+
+ if (fitem)
+ ftree = proto_item_add_subtree(fitem, ett_pvfs_fh);
+ }
+
+ /* TODO: add fh to file name snooping code here */
+
+ proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
+ PVFS2_FH_LENGTH);
+
+ dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
+
+ offset += PVFS2_FH_LENGTH;
+
+ return offset;
+}
+
+static int
+dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo, guint32 nCount)
+{
+ proto_item *extent_item = NULL;
+ proto_tree *extent_tree = NULL;
+
+ if (tree)
+ {
+ extent_item = proto_tree_add_text(tree, tvb, offset, 8,
+ "Item %d", nCount);
+
+ if (extent_item)
+ extent_tree = proto_item_add_subtree(extent_item,
+ ett_pvfs_extent_item);
+ }
+
+ /* first handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
+ NULL);
+
+ /* last handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
+ NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint32 extent_count = 0;
+ guint32 nCount;
+ proto_item *extent_array_item = NULL;
+ proto_tree *extent_array_tree = NULL;
+
+ /* extent count */
+ extent_count = tvb_get_letohl(tvb, offset);
+
+ if (tree)
+ extent_array_item = proto_tree_add_text(tree, tvb, offset, 4,
+ "Handle Extent Array (count = %d)", extent_count);
+
+ offset += 4;
+
+ if (extent_count > 0)
+ {
+ if (extent_array_item)
+ extent_array_tree = proto_item_add_subtree(extent_array_item,
+ ett_pvfs_extent_array_tree);
+
+ /* Add extent array items */
+ for (nCount = 0; nCount < extent_count; nCount++)
+ offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
+ pinfo, nCount);
+ }
+
+ return offset;
+}
+
+static int
+dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
+ int hf_time, int hf_time_sec, int hf_time_nsec)
+{
+ guint32 seconds;
+ guint32 nseconds;
+ nstime_t ts;
+ proto_item *time_item = NULL;
+ proto_tree *time_tree = NULL;
+
+ ts.secs = seconds = tvb_get_letohl(tvb, offset);
+ ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
+
+ if (tree)
+ {
+ time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
+
+ if (time_item)
+ time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
+ }
+
+ if (time_tree)
+ {
+ proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
+ proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4,
+ nseconds);
+ }
+
+ offset += 8;
+ return offset;
+}
+
+static
+int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
+ int hfindex, guint64 *pvalue)
+{
+ guint64 val;
+
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+
+ proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
+
+ if (pvalue)
+ *pvalue = val;
+
+ return offset + 8;
+}
+
+/* Taken from pvfs2-dist-simple-stripe.h */
+#define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
+#define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
+
+static int
+dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ proto_item *dist_item = NULL;
+ proto_tree *dist_tree = NULL;
+ char *distname = NULL;
+ guint32 distlen = 0;
+ char *tmpstr = NULL;
+ guint8 issimplestripe = 0;
+
+ /* Get distribution name length */
+ distlen = tvb_get_letohl(tvb, offset);
+
+ /* Get distribution name */
+ tmpstr = (char *) tvb_get_ephemeral_string(tvb, offset + 4, distlen);
+
+ if (tree)
+ {
+ guint32 total_len;
+
+ /* 'distlen' does not include the NULL terminator */
+ total_len = roundup8(4 + distlen + 1);
+
+ if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
+ (strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
+ distlen) == 0))
+ {
+ /* Parameter for 'simple_stripe' is 8 bytes */
+ total_len += 8;
+
+ issimplestripe = 1;
+ }
+
+ dist_item = proto_tree_add_text(tree, tvb, offset, total_len + 8,
+ "Distribution: %s", tmpstr);
+
+ if (dist_item)
+ dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
+ }
+
+ /* io_dist */
+ offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
+ &distname);
+
+ /* TODO: only one distribution type is currently supported */
+ if (issimplestripe)
+ offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
+ hf_pvfs_strip_size, NULL);
+
+ offset += 8;
+
+ return offset;
+}
+
+static int
+dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint32 dfile_count, i;
+
+ /* dfile_count */
+ dfile_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "dfile_count: %d",
+ dfile_count);
+ offset += 4;
+
+ for (i = 0; i < dfile_count; i++)
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ gint32 ds_type = 0;
+ guint32 attrmask = 0;
+ proto_item *attr_item = NULL;
+ proto_tree *attr_tree = NULL;
+
+ if (tree)
+ {
+ attr_item = proto_tree_add_text(tree, tvb, offset, -1, "Attributes");
+
+ if (attr_item)
+ attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr_tree);
+ }
+
+ /* UID */
+ proto_tree_add_text(attr_tree, tvb, offset, 4, "UID: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* GID */
+ proto_tree_add_text(attr_tree, tvb, offset, 4, "GID: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* Permissions */
+ proto_tree_add_text(attr_tree, tvb, offset, 4, "Permissions: %o",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset += 4;
+
+ /* atime */
+ offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
+ hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
+
+ /* mtime */
+ offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
+ hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
+
+ /* ctime */
+ offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
+ hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
+
+ /* attrmask */
+ offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
+
+ /* objtype */
+ offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
+
+ if (attrmask & PVFS_ATTR_META_DIST)
+ {
+ offset = dissect_pvfs_distribution(tvb, attr_tree, offset);
+
+ offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
+ }
+ else
+ {
+ if (attrmask & PVFS_ATTR_META_DFILES)
+ {
+ offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
+ }
+ else
+ {
+ if (attrmask & PVFS_ATTR_DATA_SIZE)
+ {
+ offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
+ NULL);
+ }
+ else
+ {
+ if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
+ {
+ /* target_path_len */
+ proto_tree_add_text(attr_tree, tvb, offset, 4,
+ "target_path_len: %d", tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset += 4;
+
+ /* target_path */
+ offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
+ offset, NULL);
+ }
+ else
+ {
+ if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
+ {
+ offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
+ hf_pvfs_size, NULL);
+ }
+ }
+ }
+ }
+ }
+
+ return offset;
+}
+
+static int
+dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ proto_tree_add_uint(tree, hf_pvfs_io_type, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ proto_tree_add_uint(tree, hf_pvfs_flowproto_type, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint32 server_param = 0;
+ guint32 lowpart;
+
+ /* server_param */
+ server_param = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
+ server_param);
+ offset += 4;
+
+ switch (server_param)
+ {
+ case PVFS_SERV_PARAM_MODE:
+ lowpart = tvb_get_letohl(tvb, offset);
+
+ proto_tree_add_text(tree, tvb, offset, 8,
+ "Server Mode: %s (%u)",
+ val_to_str(lowpart, names_pvfs_server_mode, "%u"), lowpart);
+ break;
+
+ case PVFS_SERV_PARAM_FSID_CHECK:
+ lowpart = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4, lowpart);
+ proto_tree_add_uint(tree, hf_pvfs_unused, tvb, offset + 4, 4,
+ tvb_get_letohl(tvb, offset + 4));
+ break;
+
+ case PVFS_SERV_PARAM_ROOT_CHECK:
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+ break;
+ }
+
+ offset += 8;
+
+ return offset;
+}
+
+static int
+dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ if (tree)
+ proto_tree_add_uint(tree, hf_pvfs_fs_id, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+
+ offset += 4;
+
+ return offset;
+}
+
+/*
+ * =======================================================================
+ * Request handlers
+ * =======================================================================
+ */
+
+static int
+dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* type */
+ offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
+
+ offset += 4;
+
+ offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ guint64 val = 0;
+ gint32 ereg, sreg;
+
+ /* offset */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
+ offset += 8;
+
+ /* TODO: num_eregs */
+ proto_tree_add_uint(tree, hf_pvfs_num_eregs, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* TODO: num_blocks */
+ proto_tree_add_uint(tree, hf_pvfs_num_blocks, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* TODO: stride */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_stride, tvb, offset, 8, val);
+ offset += 8;
+
+ /* TODO: ub */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_ub, tvb, offset, 8, val);
+ offset += 8;
+
+ /* TODO: lb */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_lb, tvb, offset, 8, val);
+ offset += 8;
+
+ /* TODO: aggregate size */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_aggregate_size, tvb, offset, 8, val);
+ offset += 8;
+
+ /* num_contig_chunks */
+ proto_tree_add_uint(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* depth */
+ proto_tree_add_text(tree, tvb, offset, 4, "depth: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* num_nested_req */
+ proto_tree_add_text(tree, tvb, offset, 4, "num_nested_req: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* committed */
+ proto_tree_add_text(tree, tvb, offset, 4, "committed: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* refcount */
+ proto_tree_add_text(tree, tvb, offset, 4, "refcount: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* documented */
+ offset += 4;
+
+ /* ereg */
+ ereg = tvb_get_letohl(tvb, offset);
+ proto_tree_add_int(tree, hf_pvfs_ereg, tvb, offset, 4, ereg);
+ offset += 4;
+
+ /* sreg */
+ sreg = tvb_get_letohl(tvb, offset);
+ proto_tree_add_int(tree, hf_pvfs_sreg, tvb, offset, 4, sreg);
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint64 val;
+
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* skip4 as per source code */
+ offset += 4;
+
+ /* io_type */
+ offset = dissect_pvfs_io_type(tvb, tree, offset);
+
+ /* flow_type */
+ offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
+
+ /* server_nr */
+ proto_tree_add_uint(tree, hf_pvfs_server_nr, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* server_ct */
+ proto_tree_add_uint(tree, hf_pvfs_server_count, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* Distribution */
+ offset = dissect_pvfs_distribution(tvb, tree, offset);
+
+ proto_tree_add_text(tree, tvb, offset, 4, "numreq: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* */
+ offset += 4;
+
+ offset = dissect_pvfs_pint_request(tvb, tree, offset);
+
+ /* TODO: remove this!!! */
+ offset = tvb_length(tvb) - 16;
+
+ /* offset */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_offset, tvb, offset, 8, val);
+ offset += 8;
+
+ /* size */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
+ offset += 8;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* attrmask */
+ offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* parent_ref: fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
+
+ return offset;
+}
+
+/* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
+static int
+dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* Path */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ /* starting_handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* attribute mask */
+ offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* Filename */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
+
+ /* parent_handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ /* atime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
+ hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
+
+ /* mtime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
+ hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
+
+ /* ctime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
+ hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
+
+ return offset;
+}
+
+/* TODO: incomplete */
+static int
+dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* path */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ /* atime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
+ hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
+
+ /* mtime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
+ hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
+
+ /* ctime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
+ hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* path */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+
+ /* New directory entry handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
+ NULL);
+
+ /* Parent handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* Parent atime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
+ hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
+
+ /* Parent mtime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
+ hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
+
+ /* Parent ctime */
+ offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
+ hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint64 val;
+
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ /* size */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_size, tvb, offset, 8, val);
+ offset += 8;
+
+ /* TODO: flags */
+ proto_tree_add_text(tree, tvb, offset, 4, "flags: %u",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint count, i;
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ /* attr */
+ offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
+
+ /* handle_extent_array */
+ count = tvb_get_letohl(tvb, offset);
+ offset += 4;
+
+ for (i = 0; i < count; i++)
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* object_ref: handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* object_ref: fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* ds_position */
+ proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* dirent_limit */
+ proto_tree_add_text(tree, tvb, offset, 4, "dirent_limit: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* flags */
+ proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* server_param */
+ offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo _U_)
+{
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
+ int offset, packet_info *pinfo _U_)
+{
+ /* TODO: next_id */
+ proto_tree_add_text(tree, tvb, offset, 4, "next_id: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* TODO: count */
+ proto_tree_add_text(tree, tvb, offset, 4, "count: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
+ proto_tree *tree, int offset, packet_info *pinfo)
+{
+ guint32 handle_count, i;
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* handle count */
+ handle_count = tvb_get_letohl(tvb, offset);
+ offset += 4;
+
+ for (i = 0; i < handle_count; i++)
+ {
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+ }
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo _U_)
+{
+ /* event_count */
+ proto_tree_add_text(tree, tvb, offset, 4, "Event count: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
+ proto_tree *tree, int offset, packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* */
+ offset += 4;
+
+ /* entry */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
+ proto_tree *tree, int offset, packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ return offset;
+}
+
+/* TODO: untested/incomplete */
+static int
+dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ /* attribute key */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
+ NULL);
+
+ /* attribute value */
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
+ NULL);
+
+ return offset;
+}
+
+/* TODO: incomplete/untested */
+static int
+dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ guint32 nKey, i;
+
+ /* number of keys and vals */
+ nKey = tvb_get_letohl(tvb, offset);
+ offset += 4;
+
+ for (i = 0; i < nKey; i++)
+ offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
+
+ return offset;
+}
+
+/* TODO: incomplete/untested */
+static int
+dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ offset = dissect_ds_keyval_array(tvb, tree, offset);
+
+ return offset;
+}
+
+/* TODO: incomplete/untested */
+static int
+dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ offset += 4;
+
+ offset = dissect_ds_keyval_array(tvb, tree, offset);
+
+ return offset;
+}
+
+/* TODO: untested */
+static int
+dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* key */
+ offset = dissect_pvfs_ds_keyval(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_release_number(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ guint32 release_nr = tvb_get_letohl(tvb, offset);
+
+ proto_tree_add_text(tree, tvb, offset, 4,
+ "PVFS2 Release Number: %d (%d.%d.%d)",
+ release_nr,
+ release_nr / 10000,
+ (release_nr % 10000) / 100,
+ (release_nr % 10000) % 100);
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ /* PVFS release number */
+ offset = dissect_pvfs2_release_number(tvb, tree, offset);
+
+ /* wire encoding type */
+ proto_tree_add_uint(tree, hf_pvfs_encoding, tvb, offset,
+ 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* server op */
+ proto_tree_add_uint(tree, hf_pvfs_server_op, tvb, offset, 4,
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo, guint32 server_op)
+{
+ /* context_id */
+ proto_tree_add_uint(tree, hf_pvfs_context_id, tvb, offset,
+ 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* credentials */
+ offset = dissect_pvfs_credentials(tvb, tree, offset);
+
+ switch (server_op)
+ {
+ case PVFS_SERV_CREATE:
+ offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_REMOVE:
+ offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_IO:
+ offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_GETATTR:
+ offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_SETATTR:
+ offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_LOOKUP_PATH:
+ offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_CRDIRENT:
+ offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_RMDIRENT:
+ offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_CHDIRENT:
+ offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_TRUNCATE:
+ offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_MKDIR:
+ offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_READDIR:
+ offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_GETCONFIG:
+ /* No parameters in request */
+ break;
+#endif
+
+#if 0
+ case PVFS_SERV_WRITE_COMPLETION:
+ /* No parameters in request */
+ break;
+#endif
+
+ case PVFS_SERV_FLUSH:
+ offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_SETPARAM:
+ offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
+ pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_MGMT_NOOP:
+ /* No parameters in request */
+ break;
+#endif
+
+ case PVFS_SERV_STATFS:
+ offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_PERF_UPDATE:
+ /* No parameters in request */
+ break;
+#endif
+
+ case PVFS_SERV_MGMT_PERF_MON:
+ offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
+ pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_ITERATE_HANDLES:
+ offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
+ offset, pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
+ offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
+ offset, pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_EVENT_MON:
+ offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
+ pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_REMOVE_OBJECT:
+ offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
+ pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_REMOVE_DIRENT:
+ offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
+ pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
+ offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
+ offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_JOB_TIMER:
+ /* No parameters in request */
+ break;
+#endif
+
+ case PVFS_SERV_PROTO_ERROR:
+ /* TODO: is this necessary? */
+ break;
+
+ case PVFS_SERV_GETEATTR:
+ offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_SETEATTR:
+ offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_DELEATTR:
+ offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
+ break;
+
+ default:
+ /* TODO: what should we do here? */
+ break;
+ }
+
+ return offset;
+}
+
+/*
+ * =======================================================================
+ * Response handlers
+ * =======================================================================
+ */
+
+static int
+dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* Handle */
+ return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+}
+
+static int
+dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
+}
+
+static int
+dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ guint32 nCount = 0;
+ guint32 handle_count = 0;
+ guint32 attr_count = 0;
+ proto_item *attr_item = NULL;
+ proto_tree *attr_tree = NULL;
+
+ offset += 4;
+
+ /* handle_count */
+ handle_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "Handle Count: %d",
+ handle_count);
+ offset += 4;
+
+ /* TODO: add bounds checking */
+ for (nCount = 0; nCount < handle_count; nCount++)
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ offset += 4;
+
+ /* array of attributes */
+ attr_count = tvb_get_letohl(tvb, offset);
+
+ if (tree)
+ {
+ attr_item = proto_tree_add_text(tree, tvb, offset, 4,
+ "Attribute array (total items: %d)", attr_count);
+
+ if (attr_item)
+ attr_tree = proto_item_add_subtree(attr_item, ett_pvfs_attr);
+ }
+
+ offset += 4;
+
+ /* Array of attributes */
+ for (nCount = 0; nCount < attr_count; nCount++)
+ offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ /* Handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ guint64 val;
+ guint32 dirent_count = 0;
+ guint32 nCount = 0;
+
+ /* ds_position */
+ proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset += 4;
+
+ /* directory_version */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint64(tree, hf_pvfs_directory_version, tvb, offset, 8,
+ val);
+ offset += 8;
+
+ offset += 4;
+
+ /* dirent_count */
+ dirent_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "dirent_count: %d",
+ dirent_count);
+ offset += 4;
+
+ for (nCount = 0; nCount < dirent_count; nCount++)
+ {
+ offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, NULL);
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+ }
+
+ return offset;
+}
+
+/*
+ * TODO: this code needs work! Not finished yet!
+ */
+static int
+dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
+ int offset)
+{
+ guint32 i;
+ guint32 total_bytes = 0, total_config_bytes = 0, total_lines = 0;
+ guint32 bytes_processed = 0;
+ guint32 length_remaining = 0;
+ char *ptr = NULL;
+ proto_item *item = NULL, *config_item = NULL;
+ proto_tree *tree = NULL, *config_tree = NULL;
+ guint8 truncated = 0;
+
+ if (parent_tree)
+ {
+ item = proto_tree_add_text(parent_tree, tvb, offset, 12,
+ "Server Config");
+
+ if (item)
+ tree = proto_item_add_subtree(item, ett_pvfs_server_config);
+ }
+
+ /* Total number of bytes in server config (incl. entry count) */
+ total_bytes = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "Total Bytes: %d",
+ total_bytes);
+ offset += 4;
+
+ /* There must be at least 4 bytes of data returned to determine the
+ * size of the server config data
+ */
+ if (total_bytes < 4)
+ {
+ /* Server config not returned, bail out */
+ return offset;
+ }
+
+ /* Number of entries in server config */
+ total_lines = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "Lines: %d", total_lines);
+ offset += 4;
+
+ /* Number of bytes in server config */
+ total_config_bytes = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "Config Bytes: %d",
+ total_config_bytes);
+ offset += 4;
+
+ /* Get pointer to server config data */
+ ptr = (char *) tvb_get_ptr(tvb, offset, total_config_bytes);
+
+ /* Check if all data is available */
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ if (length_remaining < total_config_bytes)
+ {
+ total_config_bytes = length_remaining;
+
+ truncated = 1;
+ }
+
+ bytes_processed = 0;
+
+ for (i = 0; i < total_lines; i++)
+ {
+ guint8 entry[256], *pentry = entry, *tmp_entry = NULL;
+ guint32 entry_length = 0, tmp_entry_length = 0;
+ guint32 bufsiz = sizeof(entry);
+
+ while ((*ptr != '\n') && (*ptr != '\0') &&
+ (bytes_processed < total_config_bytes) &&
+ (entry_length < bufsiz))
+ {
+ *pentry++ = *ptr++;
+
+ bytes_processed++;
+ entry_length++;
+ }
+
+ if ((entry_length == bufsiz) &&
+ ((entry[entry_length - 1] != '\n') ||
+ (entry[entry_length - 1] != '\0')))
+ {
+ /*
+ * Single line of config data doesn't fit into provided buffer,
+ * config data is malformed.
+ */
+
+ break;
+ }
+
+ if (bytes_processed == total_config_bytes)
+ {
+ /* Oops... ran out of data before we could complete the entry */
+ break;
+ }
+
+ *pentry= '\0';
+
+ tmp_entry = entry;
+ tmp_entry_length = entry_length;
+
+ /* Remove all whitespace from front of entry */
+ while ((tmp_entry_length > 0) && (!isalnum(*tmp_entry)) &&
+ (*tmp_entry != '<'))
+ {
+ tmp_entry++;
+ tmp_entry_length--;
+ }
+
+ if (tmp_entry[0] == '<')
+ {
+ if (tmp_entry[tmp_entry_length - 1] == '>')
+ {
+ /* Token */
+ if (tmp_entry[1] != '/')
+ {
+ /* Opening token, create new tree root */
+ config_item = proto_tree_add_text(tree, tvb, offset,
+ tmp_entry_length, "%s", tmp_entry);
+
+ if (config_item)
+ config_tree = proto_item_add_subtree(config_item,
+ ett_pvfs_server_config_branch);
+ }
+ else
+ {
+ /* Closing token */
+ config_item = NULL;
+ config_tree = NULL;
+ }
+ }
+ else
+ {
+ /* Malformed token */
+ break;
+ }
+ }
+ else
+ {
+ /* Insert items into the root config tree if there's no subtree
+ * defined.
+ */
+ if (config_tree == NULL)
+ config_tree = tree;
+
+ if (tmp_entry_length > 0)
+ {
+ proto_tree_add_text(config_tree, tvb, offset, tmp_entry_length,
+ "%s", tmp_entry);
+ }
+ }
+
+ offset += entry_length + 1;
+
+ ptr++;
+ bytes_processed++;
+ }
+
+ if (bytes_processed < total_config_bytes)
+ {
+ /* We ran out of server config data */
+ proto_tree_add_text(config_tree, tvb, offset, -1,
+ "<MALFORMED OR TRUNCATED DATA>");
+ }
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset)
+{
+ /* size */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
+ NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset)
+{
+ guint64 val;
+
+ /* old_value */
+ val = ((guint64) tvb_get_letohl(tvb, offset + 4)) << 32 |
+ tvb_get_letohl(tvb, offset);
+
+ proto_tree_add_uint64(tree, hf_pvfs_prev_value, tvb, offset, 8, val);
+
+ offset += 8;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+ offset += 4;
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ /* bytes_available */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
+ NULL);
+
+ /* bytes_total */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
+ NULL);
+
+ /* RAM bytes total */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
+ NULL);
+
+ /* RAM bytes free */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
+ NULL);
+
+ /* load average (1s) */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
+ NULL);
+
+ /* load average (5s) */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
+ NULL);
+
+ /* load average (15s) */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
+ NULL);
+
+ /* uptime (seconds) */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
+ NULL);
+
+ /* handles_available_count */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
+ NULL);
+
+ /* handles_total_count */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
+ NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
+ int nItem)
+{
+ proto_item *stat_item = NULL;
+ proto_tree *stat_tree = NULL;
+
+ if (tree)
+ {
+ stat_item = proto_tree_add_text(tree, tvb, offset, 48,
+ "Stat Array - Element %d", nItem);
+
+ if (stat_item)
+ stat_tree = proto_item_add_subtree(stat_item,
+ ett_pvfs_mgmt_perf_stat);
+ }
+
+ /* TODO: valid_flag */
+ proto_tree_add_text(stat_tree, tvb, offset, 4, "valid_flag: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* TODO: id */
+ proto_tree_add_text(stat_tree, tvb, offset, 4, "id: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
+ NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset)
+{
+ guint32 perf_array_count, i;
+
+ /* TODO: suggested_next_id */
+ proto_tree_add_text(tree, tvb, offset, 4, "suggested_next_id: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset += 4;
+
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms,
+ NULL);
+
+ offset += 4;
+
+ /* TODO: perf_array_count */
+ perf_array_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "perf_array_count: %d",
+ perf_array_count);
+ offset += 4;
+
+ for (i = 0; i < perf_array_count; i++)
+ offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ guint32 handle_count, i;
+
+ /* ds_position */
+ proto_tree_add_text(tree, tvb, offset, 4, "ds_position: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* handle_count */
+ handle_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "handle_count: %d",
+ handle_count);
+ offset += 4;
+
+ /* TODO: this could be improved */
+ for (i = 0; i < handle_count; i++)
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo)
+{
+ offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+ offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
+ NULL);
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
+ NULL);
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ guint32 dspace_info_count, i;
+ proto_item *arr_item = NULL;
+ proto_tree *arr_tree = NULL;
+
+ offset += 4;
+
+ /* dspace_info_count */
+ dspace_info_count = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "dspace_info_count: %d",
+ dspace_info_count);
+
+ if ((dspace_info_count > 0) && (tree))
+ {
+ arr_item = proto_tree_add_text(tree, tvb, offset,
+ dspace_info_count * 40, "dspace_info Array (%d items)",
+ dspace_info_count);
+
+ if (arr_item)
+ arr_tree = proto_item_add_subtree(arr_item,
+ ett_pvfs_mgmt_dspace_info);
+ }
+
+ for (i = 0; i < dspace_info_count; i++)
+ offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset)
+{
+ /* api */
+ proto_tree_add_text(tree, tvb, offset, 4, "api: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* operation */
+ proto_tree_add_text(tree, tvb, offset, 4, "operation: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* value */
+ proto_tree_add_text(tree, tvb, offset, 4, "value: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* id */
+ offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
+ NULL);
+
+ /* flags */
+ proto_tree_add_text(tree, tvb, offset, 4, "flags: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* tv_sec */
+ proto_tree_add_text(tree, tvb, offset, 4, "tv_sec: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* tv_usec */
+ proto_tree_add_text(tree, tvb, offset, 4, "tv_usec: %d",
+ tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ offset += 4;
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
+ int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ /* fs_id */
+ offset = dissect_pvfs_fs_id(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
+ proto_tree *tree, int offset, packet_info *pinfo)
+{
+ /* handle */
+ offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
+
+ return offset;
+}
+
+/* TODO: untested */
+static int
+dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo _U_)
+{
+ offset += 4;
+
+ /* Dissect nKey & ds_keyval array */
+ offset = dissect_ds_keyval_array(tvb, tree, offset);
+
+ return offset;
+}
+
+static int
+dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
+ packet_info *pinfo, guint32 server_op)
+{
+ /* error code */
+ offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
+
+ switch (server_op)
+ {
+ case PVFS_SERV_CREATE:
+ offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_REMOVE:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_IO:
+ offset = dissect_pvfs2_io_response(tvb, tree, offset);
+ break;
+
+ case PVFS_SERV_GETATTR:
+ offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_SETATTR:
+ /* No result data */
+ break;
+
+ case PVFS_SERV_LOOKUP_PATH:
+ offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_CRDIRENT:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_RMDIRENT:
+ offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_CHDIRENT:
+ offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_TRUNCATE:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_MKDIR:
+ offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_READDIR:
+ offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
+ break;
+
+ case PVFS_SERV_GETCONFIG:
+ offset = dissect_pvfs2_getconfig_response(tvb, tree, offset);
+ break;
+
+ case PVFS_SERV_WRITE_COMPLETION:
+ offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
+ break;
+
+#if 0
+ case PVFS_SERV_FLUSH:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_MGMT_SETPARAM:
+ offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
+ break;
+
+#if 0
+ case PVFS_SERV_MGMT_NOOP:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_STATFS:
+ offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
+ break;
+
+#if 0
+ case PVFS_SERV_PERF_UPDATE:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_MGMT_PERF_MON:
+ offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
+ break;
+
+ case PVFS_SERV_MGMT_ITERATE_HANDLES:
+ offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
+ offset, pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
+ offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
+ offset, pinfo);
+ break;
+
+ case PVFS_SERV_MGMT_EVENT_MON:
+ offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
+ break;
+
+ case PVFS_SERV_MGMT_REMOVE_OBJECT:
+ offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
+ pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_MGMT_REMOVE_DIRENT:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
+ offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
+ offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_JOB_TIMER:
+ /* No result data */
+ break;
+#endif
+
+ case PVFS_SERV_PROTO_ERROR:
+ /* No result data */
+ break;
+
+ /* TODO: untested */
+ case PVFS_SERV_GETEATTR:
+ offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
+ break;
+
+#if 0
+ case PVFS_SERV_SETEATTR:
+ /* No result data */
+ break;
+#endif
+
+#if 0
+ case PVFS_SERV_DELEATTR:
+ /* No result data */
+ break;
+#endif
+
+ default:
+ /* TODO: what do we do here? */
+ break;
+ }
+
+ return offset;
+}
+
+static GHashTable *pvfs2_io_tracking_value_table = NULL;
+
+typedef struct pvfs2_io_tracking_key
+{
+ guint64 tag;
+} pvfs2_io_tracking_key_t;
+
+typedef struct pvfs2_io_tracking_value
+{
+ guint32 request_frame_num;
+ guint32 response_frame_num;
+ guint32 flow_frame_num;
+
+} pvfs2_io_tracking_value_t;
+
+static gint
+pvfs2_io_tracking_equal(gconstpointer k1, gconstpointer k2)
+{
+ const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
+ const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
+
+ return (key1->tag == key2->tag);
+}
+
+static guint
+pvfs2_io_tracking_hash(gconstpointer k)
+{
+ const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
+
+ return (key->tag >> 32) ^ ((guint32) key->tag);
+}
+
+static void
+pvfs2_io_tracking_init(void)
+{
+ if (pvfs2_io_tracking_value_table != NULL)
+ g_hash_table_destroy(pvfs2_io_tracking_value_table);
+
+ pvfs2_io_tracking_value_table = g_hash_table_new(pvfs2_io_tracking_hash,
+ pvfs2_io_tracking_equal);
+}
+
+static pvfs2_io_tracking_value_t *
+pvfs2_io_tracking_new_with_tag(guint64 tag, guint32 num)
+{
+ pvfs2_io_tracking_value_t *value;
+ pvfs2_io_tracking_key_t *newkey;
+
+ newkey = (pvfs2_io_tracking_key_t *) se_alloc(sizeof(*newkey));
+ memset(newkey, 0, sizeof(*newkey));
+ newkey->tag = tag;
+
+ value = se_alloc(sizeof(*value));
+ memset(value, 0, sizeof(*value));
+
+ g_hash_table_insert(pvfs2_io_tracking_value_table, newkey, value);
+
+ value->request_frame_num = num;
+
+ return value;
+}
+
+static gboolean
+dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+ gboolean dissect_other_as_continuation _U_)
+{
+ guint32 mode = 0;
+ proto_item *item = NULL, *hitem = NULL;
+ proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
+ int offset = 0;
+ guint64 tag;
+ guint32 server_op;
+ pvfs2_io_tracking_value_t *val = NULL;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (parent_tree)
+ {
+ item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, FALSE);
+
+ if (item)
+ pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
+ }
+
+ proto_tree_add_text(pvfs_tree, tvb, 0, -1, "Version: 2");
+
+ /* PVFS packet header is 24 bytes */
+ hitem = proto_tree_add_text(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
+ "BMI Header");
+ if (hitem)
+ pvfs_htree = proto_item_add_subtree(hitem, ett_pvfs_hdr);
+
+ /* Magic number */
+ proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* TCP message mode (32-bit) */
+ mode = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
+ offset += 4;
+
+ /* tag (64-bit) */
+ offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
+
+ /* size (64-bit) */
+ offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
+
+ /* Lookahead to get server_op (invalid if frame contains flow data) */
+ server_op = tvb_get_letohl(tvb, offset + 8);
+
+ if (mode == TCP_MODE_UNEXP)
+ {
+ /* Add entry to tracking table for PVFS_SERV_IO request */
+ if ((server_op == PVFS_SERV_IO) && !pinfo->fd->flags.visited)
+ val = pvfs2_io_tracking_new_with_tag(tag, pinfo->fd->num);
+ }
+ else
+ {
+ pvfs2_io_tracking_key_t key;
+
+ memset(&key, 0, sizeof(key));
+ key.tag = tag;
+
+ val = g_hash_table_lookup(pvfs2_io_tracking_value_table, &key);
+
+ /* If this frame contains a known PVFS_SERV_IO tag, track it */
+ if (val && !pinfo->fd->flags.visited)
+ {
+ /* If response HAS NOT been seen, mark this frame as response */
+ if (val->response_frame_num == 0)
+ val->response_frame_num = pinfo->fd->num;
+ else
+ {
+ /* If response HAS been seen, this frame is flow data */
+ if (val->flow_frame_num == 0)
+ val->flow_frame_num = pinfo->fd->num;
+ }
+ }
+ }
+
+ if (val && (val->flow_frame_num == pinfo->fd->num))
+ {
+ /* This frame is marked as being flow data */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
+
+ proto_tree_add_text(pvfs_tree, tvb, offset, -1, "<data>");
+
+ return TRUE;
+ }
+
+ /* Extract common part of packet found in requests and responses */
+ offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
+
+ /* Update column info display */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_set_str(pinfo->cinfo, COL_INFO,
+ val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
+
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
+ }
+
+ /* TODO: handle all modes */
+ if (mode == TCP_MODE_UNEXP)
+ {
+ /* Request */
+ offset = dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
+ }
+ else
+ {
+ /* TODO: re-examine this! */
+#if 0
+ if (mode == TCP_MODE_REND)
+ {
+ /*
+ * TODO: move this code outside so it's common for requests and
+ * responses
+ */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
+ }
+ else
+#endif
+ {
+ /* Response */
+ offset = dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
+ server_op);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Register the protocol with Ethereal */
+void
+proto_register_pvfs(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pvfs_magic_nr,
+ { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
+ NULL, 0, "Magic Number", HFILL }},
+
+ { &hf_pvfs_mode,
+ { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_mode), 0, "Mode", HFILL }},
+
+ { &hf_pvfs_tag,
+ { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
+ NULL, 0, "Tag", HFILL }},
+
+ { &hf_pvfs_size,
+ { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
+ NULL, 0, "Size", HFILL }},
+
+ { &hf_pvfs_release_number,
+ { "Release Number", "pvfs.release_number", FT_UINT32, BASE_DEC,
+ NULL, 0, "Release Number", HFILL }},
+
+ { &hf_pvfs_encoding,
+ { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_encoding), 0, "Encoding", HFILL }},
+
+ { &hf_pvfs_server_op,
+ { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_server_op), 0, "Server Operation", HFILL }},
+
+ { &hf_pvfs_handle,
+ { "Handle", "pvfs.handle", FT_BYTES, BASE_HEX,
+ NULL, 0, "Handle", HFILL }},
+
+ { &hf_pvfs_fs_id,
+ { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
+ NULL, 0, "File System ID", HFILL }},
+
+ { &hf_pvfs_attrmask,
+ { "attrmask", "pvfs.attrmask", FT_UINT32, BASE_HEX,
+ NULL, 0, "Attribute Mask", HFILL }},
+
+ { &hf_pvfs_attr,
+ { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
+ VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
+
+ { &hf_pvfs_ds_type,
+ { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
+ VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
+
+ { &hf_pvfs_error,
+ { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
+ VALS(names_pvfs_error), 0, "Result", HFILL }},
+
+ { &hf_pvfs_atime,
+ { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Access Time", HFILL }},
+
+ { &hf_pvfs_atime_sec,
+ { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Access Time (seconds)", HFILL }},
+
+ { &hf_pvfs_atime_nsec,
+ { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Access Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_mtime,
+ { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Modify Time", HFILL }},
+
+ { &hf_pvfs_mtime_sec,
+ { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Modify Time (seconds)", HFILL }},
+
+ { &hf_pvfs_mtime_nsec,
+ { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Modify Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_ctime,
+ { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Creation Time", HFILL }},
+
+ { &hf_pvfs_ctime_sec,
+ { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Creation Time (seconds)", HFILL }},
+
+ { &hf_pvfs_ctime_nsec,
+ { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Creation Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_parent_atime,
+ { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Access Time", HFILL }},
+
+ { &hf_pvfs_parent_atime_sec,
+ { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Access Time (seconds)", HFILL }},
+
+ { &hf_pvfs_parent_atime_nsec,
+ { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Access Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_parent_mtime,
+ { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Modify Time", HFILL }},
+
+ { &hf_pvfs_parent_mtime_sec,
+ { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Modify Time (seconds)", HFILL }},
+
+ { &hf_pvfs_parent_mtime_nsec,
+ { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Modify Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_parent_ctime,
+ { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Creation Time", HFILL }},
+
+ { &hf_pvfs_parent_ctime_sec,
+ { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Creation Time (seconds)", HFILL }},
+
+ { &hf_pvfs_parent_ctime_nsec,
+ { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
+ NULL, 0, "Creation Time (microseconds)", HFILL }},
+
+ { &hf_pvfs_dirent_count,
+ { "Dir Entry Count", "pvfs.dirent_count", FT_UINT64, BASE_DEC,
+ NULL, 0, "Directory Entry Count", HFILL }},
+
+ { &hf_pvfs_directory_version,
+ { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
+ NULL, 0, "Directory Version", HFILL }},
+
+ { &hf_pvfs_path,
+ { "Path", "pvfs.path", FT_STRING, BASE_DEC,
+ NULL, 0, "Path", HFILL }},
+
+ { &hf_pvfs_total_completed,
+ { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
+ NULL, 0, "Bytes Completed", HFILL }},
+
+ { &hf_pvfs_io_dist,
+ { "Name", "pvfs.distribution.name", FT_STRING, BASE_DEC,
+ NULL, 0, "Distribution Name", HFILL }},
+
+ { &hf_pvfs_aggregate_size,
+ { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
+ NULL, 0, "Aggregate Size", HFILL }},
+
+ { &hf_pvfs_io_type,
+ { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_io_type), 0, "I/O Type", HFILL }},
+
+ { &hf_pvfs_flowproto_type,
+ { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_flowproto_type), 0, "Flow Protocol Type", HFILL }},
+
+ { &hf_pvfs_server_param,
+ { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
+ VALS(names_pvfs_server_param), 0, "Server Parameter", HFILL }},
+
+ { &hf_pvfs_prev_value,
+ { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
+ NULL, 0, "Previous Value", HFILL }},
+
+ { &hf_pvfs_ram_free_bytes,
+ { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
+ NULL, 0, "RAM Free Bytes", HFILL }},
+
+ { &hf_pvfs_bytes_available,
+ { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
+ NULL, 0, "Bytes Available", HFILL }},
+
+ { &hf_pvfs_bytes_total,
+ { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
+ NULL, 0, "Bytes Total", HFILL }},
+
+ { &hf_pvfs_ram_bytes_total,
+ { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
+ NULL, 0, "RAM Bytes Total", HFILL }},
+
+ { &hf_pvfs_ram_bytes_free,
+ { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
+ NULL, 0, "RAM Bytes Free", HFILL }},
+
+ { &hf_pvfs_load_average_1s,
+ { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
+ NULL, 0, "Load Average (1s)", HFILL }},
+
+ { &hf_pvfs_load_average_5s,
+ { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
+ NULL, 0, "Load Average (5s)", HFILL }},
+
+ { &hf_pvfs_load_average_15s,
+ { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
+ NULL, 0, "Load Average (15s)", HFILL }},
+
+ { &hf_pvfs_uptime_seconds,
+ { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
+ NULL, 0, "Uptime (seconds)", HFILL }},
+
+ { &hf_pvfs_handles_available,
+ { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
+ NULL, 0, "Handles Available", HFILL }},
+
+ { &hf_pvfs_handles_total,
+ { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
+ NULL, 0, "Total Handles", HFILL }},
+
+ /*
+ * This is used when the field returns 64-bits but we're only interested
+ * in the lower 32-bit bits.
+ */
+ { &hf_pvfs_unused,
+ { "Unused", "", FT_UINT32, BASE_DEC,
+ NULL, 0, "Unused", HFILL }},
+
+ { &hf_pvfs_context_id,
+ { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
+ NULL, 0, "Context ID", HFILL }},
+
+ { &hf_pvfs_offset,
+ { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
+ NULL, 0, "Offset", HFILL }},
+
+ { &hf_pvfs_stride,
+ { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
+ NULL, 0, "Stride", HFILL }},
+
+ { &hf_pvfs_ub,
+ { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
+ NULL, 0, "ub", HFILL }},
+
+ { &hf_pvfs_lb,
+ { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
+ NULL, 0, "lb", HFILL }},
+
+ { &hf_pvfs_end_time_ms,
+ { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
+ NULL, 0, "end_time_ms", HFILL }},
+
+ { &hf_pvfs_cur_time_ms,
+ { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
+ NULL, 0, "cur_time_ms", HFILL }},
+
+ { &hf_pvfs_start_time_ms,
+ { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
+ NULL, 0, "start_time_ms", HFILL }},
+
+ { &hf_pvfs_bytes_written,
+ { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
+ NULL, 0, "bytes_written", HFILL }},
+
+ { &hf_pvfs_bytes_read,
+ { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
+ NULL, 0, "bytes_read", HFILL }},
+
+ { &hf_pvfs_metadata_write,
+ { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
+ NULL, 0, "metadata_write", HFILL }},
+
+ { &hf_pvfs_metadata_read,
+ { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
+ NULL, 0, "metadata_read", HFILL }},
+
+ { &hf_pvfs_b_size,
+ { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
+ BASE_DEC, NULL, 0, "Size of bstream", HFILL }},
+
+ { &hf_pvfs_k_size,
+ { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
+ BASE_DEC, NULL, 0, "Number of keyvals", HFILL }},
+
+ { &hf_pvfs_id_gen_t,
+ { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
+ NULL, 0, "id_gen_t", HFILL }},
+
+ { &hf_pvfs_attribute_key,
+ { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_DEC,
+ NULL, 0, "Attribute key", HFILL }},
+
+ { &hf_pvfs_attribute_value,
+ { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_DEC,
+ NULL, 0, "Attribute value", HFILL }},
+
+ { &hf_pvfs_strip_size,
+ { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
+ NULL, 0, "Strip size (bytes)", HFILL }},
+
+ /* TODO: need description */
+ { &hf_pvfs_ereg,
+ { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
+ NULL, 0, "ereg", HFILL }},
+
+ /* TODO: need description */
+ { &hf_pvfs_sreg,
+ { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
+ NULL, 0, "sreg", HFILL }},
+
+ { &hf_pvfs_num_eregs,
+ { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
+ NULL, 0, "Number of eregs", HFILL }},
+
+ { &hf_pvfs_num_blocks,
+ { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
+ NULL, 0, "Number of blocks", HFILL }},
+
+ { &hf_pvfs_num_contig_chunks,
+ { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
+ BASE_DEC, NULL, 0, "Number of contig_chunks", HFILL }},
+
+ { &hf_pvfs_server_nr,
+ { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
+ NULL, 0, "Server #", HFILL }},
+
+ { &hf_pvfs_server_count,
+ { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
+ NULL, 0, "Number of servers", HFILL }},
+
+ { &hf_pvfs_fh_length,
+ { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
+ NULL, 0, "file handle length", HFILL }},
+
+ { &hf_pvfs_fh_hash,
+ { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
+ NULL, 0, "file handle hash", HFILL }},
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_pvfs,
+ &ett_pvfs_hdr,
+ &ett_pvfs_credentials,
+ &ett_pvfs_server_config,
+ &ett_pvfs_server_config_branch,
+ &ett_pvfs_attrmask,
+ &ett_pvfs_time,
+ &ett_pvfs_extent_array_tree,
+ &ett_pvfs_extent_item,
+ &ett_pvfs_string,
+ &ett_pvfs_attr_tree,
+ &ett_pvfs_distribution,
+ &ett_pvfs_mgmt_perf_stat,
+ &ett_pvfs_mgmt_dspace_info,
+ &ett_pvfs_attr,
+ &ett_pvfs_fh
+ };
+ module_t *pvfs_module;
+
+ /* Register the protocol name and description */
+ proto_pvfs = proto_register_protocol("Parallel Virtual File System",
+ "PVFS", "pvfs");
+
+ /*
+ * Required function calls to register the header fields and
+ * subtrees used
+ */
+
+ proto_register_field_array(proto_pvfs, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_init_routine(pvfs2_io_tracking_init);
+
+ pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
+ prefs_register_bool_preference(pvfs_module, "desegment",
+ "Reassemble PVFS messages spanning multiple TCP segments",
+ "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
+ "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
+ &pvfs_desegment);
+}
+
+void
+proto_reg_handoff_pvfs(void)
+{
+ dissector_handle_t pvfs_handle;
+
+ pvfs_handle = new_create_dissector_handle(dissect_pvfs_heur, proto_pvfs);
+ dissector_add("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
+
+ heur_dissector_add("tcp", dissect_pvfs_heur, proto_pvfs);
+}
+