Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
5052 lines (5051 sloc) 168 KB
diff --git a/epan/dissectors/packet-gluster.h b/epan/dissectors/packet-gluster.h
new file mode 100644
index 0000000..5a8da6e
--- /dev/null
+++ b/epan/dissectors/packet-gluster.h
@@ -0,0 +1,419 @@
+/* packet-gluster.h
+ * Header for gluster dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifndef __PACKET_GLUSTER_H__
+#define __PACKET_GLUSTER_H__
+
+#define GLUSTER_PORT 24007
+
+/* most of this comes from rpc/rpc-lib/src/protocol-common.h
+ * Some versions are commented with a user-visible version, others are not.
+ * Some programs were introduced starting version 2.
+ *
+ * Older versions were removed from the sources.
+ * One patch that did this is at http://review.gluster.com/610
+ */
+#define GLUSTERD1_MGMT_PROGRAM 1298433
+/* only available in version 1 */
+
+#define GLUSTERFS_PROGRAM 4867634 /* same as GD_BRICK_PROGRAM */
+/* only available in version 1 (replaced by GD_BRICK_PROGRAM) */
+
+/* rpc/rpc-lib/src/xdr-common.h */
+#define GLUSTER_DUMP_PROGRAM 123451501
+/* only available in version 1 */
+
+#define GLUSTER_HNDSK_PROGRAM 14398633
+/* only available in version 1 (0.0.1) */
+
+#define GLUSTER_PMAP_PROGRAM 34123456
+/* only available in version 1 */
+
+#define GLUSTER_CBK_PROGRAM 52743234
+/* only available in version 1 (0.0.1) */
+
+#define GLUSTER3_1_FOP_PROGRAM 1298437
+/* available in version 310 (3.1.0) */
+
+#define GD_MGMT_PROGRAM 1238433
+/* available in version 1 and 2 */
+
+#define GD_FRIEND_PROGRAM 1238437
+/* only available in version 2 (0.0.2) */
+
+#define GLUSTER_CLI_PROGRAM 1238463
+/* available in version 1 (0.0.1) and 2 (0.0.2) */
+
+#define GD_BRICK_PROGRAM 4867634
+/* only available in version 2 (supersedes GLUSTERFS_PROGRAM) */
+
+/* GD_MGMT_PROGRAM */
+enum gf_mgmt_procnum {
+ GD_MGMT_NULL = 0,
+ GD_MGMT_PROBE_QUERY,
+ GD_MGMT_FRIEND_ADD,
+ GD_MGMT_CLUSTER_LOCK,
+ GD_MGMT_CLUSTER_UNLOCK,
+ GD_MGMT_STAGE_OP,
+ GD_MGMT_COMMIT_OP,
+ GD_MGMT_FRIEND_REMOVE,
+ GD_MGMT_FRIEND_UPDATE,
+ GD_MGMT_CLI_PROBE,
+ GD_MGMT_CLI_DEPROBE,
+ GD_MGMT_CLI_LIST_FRIENDS,
+ GD_MGMT_CLI_CREATE_VOLUME,
+ GD_MGMT_CLI_GET_VOLUME,
+ GD_MGMT_CLI_DELETE_VOLUME,
+ GD_MGMT_CLI_START_VOLUME,
+ GD_MGMT_CLI_STOP_VOLUME,
+ GD_MGMT_CLI_RENAME_VOLUME,
+ GD_MGMT_CLI_DEFRAG_VOLUME,
+ GD_MGMT_CLI_SET_VOLUME,
+ GD_MGMT_CLI_ADD_BRICK,
+ GD_MGMT_CLI_REMOVE_BRICK,
+ GD_MGMT_CLI_REPLACE_BRICK,
+ GD_MGMT_CLI_LOG_FILENAME,
+ GD_MGMT_CLI_LOG_LOCATE,
+ GD_MGMT_CLI_LOG_ROTATE,
+ GD_MGMT_CLI_SYNC_VOLUME,
+ GD_MGMT_CLI_RESET_VOLUME,
+ GD_MGMT_CLI_FSM_LOG,
+ GD_MGMT_CLI_GSYNC_SET,
+ GD_MGMT_CLI_PROFILE_VOLUME,
+ GD_MGMT_BRICK_OP,
+ GD_MGMT_CLI_LOG_LEVEL,
+ GD_MGMT_CLI_STATUS_VOLUME,
+ GD_MGMT_MAXVALUE
+};
+
+/* GLUSTER_CLI_PROGRAM */
+enum gluster_cli_procnum {
+ GLUSTER_CLI_NULL = 0,
+ GLUSTER_CLI_PROBE,
+ GLUSTER_CLI_DEPROBE,
+ GLUSTER_CLI_LIST_FRIENDS,
+ GLUSTER_CLI_CREATE_VOLUME,
+ GLUSTER_CLI_GET_VOLUME,
+ GLUSTER_CLI_GET_NEXT_VOLUME,
+ GLUSTER_CLI_DELETE_VOLUME,
+ GLUSTER_CLI_START_VOLUME,
+ GLUSTER_CLI_STOP_VOLUME,
+ GLUSTER_CLI_RENAME_VOLUME,
+ GLUSTER_CLI_DEFRAG_VOLUME,
+ GLUSTER_CLI_SET_VOLUME,
+ GLUSTER_CLI_ADD_BRICK,
+ GLUSTER_CLI_REMOVE_BRICK,
+ GLUSTER_CLI_REPLACE_BRICK,
+ GLUSTER_CLI_LOG_FILENAME,
+ GLUSTER_CLI_LOG_LOCATE,
+ GLUSTER_CLI_LOG_ROTATE,
+ GLUSTER_CLI_GETSPEC,
+ GLUSTER_CLI_PMAP_PORTBYBRICK,
+ GLUSTER_CLI_SYNC_VOLUME,
+ GLUSTER_CLI_RESET_VOLUME,
+ GLUSTER_CLI_FSM_LOG,
+ GLUSTER_CLI_GSYNC_SET,
+ GLUSTER_CLI_PROFILE_VOLUME,
+ GLUSTER_CLI_QUOTA,
+ GLUSTER_CLI_TOP_VOLUME,
+ GLUSTER_CLI_GETWD,
+ GLUSTER_CLI_LOG_LEVEL,
+ GLUSTER_CLI_STATUS_VOLUME,
+ GLUSTER_CLI_MOUNT,
+ GLUSTER_CLI_UMOUNT,
+ GLUSTER_CLI_HEAL_VOLUME,
+ GLUSTER_CLI_STATEDUMP_VOLUME,
+ GLUSTER_CLI_MAXVALUE
+};
+
+/* GLUSTER_CLI_PROGRAM 2 */
+enum gluster_cli_2_procnum {
+ GLUSTER_CLI_2_NULL = 0, /* 0 */
+ GLUSTER_CLI_2_PROBE,
+ GLUSTER_CLI_2_DEPROBE,
+ GLUSTER_CLI_2_LIST_FRIENDS,
+ GLUSTER_CLI_2_CREATE_VOLUME,
+ GLUSTER_CLI_2_GET_VOLUME,
+ GLUSTER_CLI_2_GET_NEXT_VOLUME,
+ GLUSTER_CLI_2_DELETE_VOLUME,
+ GLUSTER_CLI_2_START_VOLUME,
+ GLUSTER_CLI_2_STOP_VOLUME,
+ GLUSTER_CLI_2_RENAME_VOLUME,
+ GLUSTER_CLI_2_DEFRAG_VOLUME,
+ GLUSTER_CLI_2_SET_VOLUME,
+ GLUSTER_CLI_2_ADD_BRICK,
+ GLUSTER_CLI_2_REMOVE_BRICK,
+ GLUSTER_CLI_2_REPLACE_BRICK,
+ GLUSTER_CLI_2_LOG_ROTATE,
+ GLUSTER_CLI_2_GETSPEC,
+ GLUSTER_CLI_2_PMAP_PORTBYBRICK,
+ GLUSTER_CLI_2_SYNC_VOLUME,
+ GLUSTER_CLI_2_RESET_VOLUME,
+ GLUSTER_CLI_2_FSM_LOG,
+ GLUSTER_CLI_2_GSYNC_SET,
+ GLUSTER_CLI_2_PROFILE_VOLUME,
+ GLUSTER_CLI_2_QUOTA,
+ GLUSTER_CLI_2_TOP_VOLUME,
+ GLUSTER_CLI_2_GETWD,
+ GLUSTER_CLI_2_STATUS_VOLUME,
+ GLUSTER_CLI_2_STATUS_ALL,
+ GLUSTER_CLI_2_MOUNT,
+ GLUSTER_CLI_2_UMOUNT,
+ GLUSTER_CLI_2_HEAL_VOLUME,
+ GLUSTER_CLI_2_STATEDUMP_VOLUME,
+ GLUSTER_CLI_2_LIST_VOLUME,
+ GLUSTER_CLI_2_CLRLOCKS_VOLUME,
+ GLUSTER_CLI_2_MAXVALUE,
+};
+
+
+/* GLUSTER_DUMP_PROGRAM */
+enum gluster_prog_dump_procs {
+ GF_DUMP_NULL = 0,
+ GF_DUMP_DUMP,
+ GF_DUMP_MAXVALUE
+};
+
+/* GLUSTERD1_MGMT_PROGRAM */
+enum glusterd_mgmt_procnum {
+ GLUSTERD_MGMT_NULL = 0,
+ GLUSTERD_MGMT_PROBE_QUERY,
+ GLUSTERD_MGMT_FRIEND_ADD,
+ GLUSTERD_MGMT_CLUSTER_LOCK,
+ GLUSTERD_MGMT_CLUSTER_UNLOCK,
+ GLUSTERD_MGMT_STAGE_OP,
+ GLUSTERD_MGMT_COMMIT_OP,
+ GLUSTERD_MGMT_FRIEND_REMOVE,
+ GLUSTERD_MGMT_FRIEND_UPDATE,
+ GLUSTERD_MGMT_MAXVALUE
+};
+
+/* GLUSTERD1_MGMT_PROGRAM for version 2*/
+enum glusterd_mgmt_2_procnum {
+ GLUSTERD_MGMT_2_NULL = 0, /* 0 */
+ GLUSTERD_MGMT_2_CLUSTER_LOCK,
+ GLUSTERD_MGMT_2_CLUSTER_UNLOCK,
+ GLUSTERD_MGMT_2_STAGE_OP,
+ GLUSTERD_MGMT_2_COMMIT_OP,
+ GLUSTERD_MGMT_2_MAXVALUE,
+};
+
+
+/* GLUSTERFS_PROGRAM */
+enum gf_brick_procnum {
+ GF_BRICK_NULL = 0,
+ GF_BRICK_TERMINATE,
+ GF_BRICK_XLATOR_INFO,
+ GF_BRICK_XLATOR_HEAL,
+ GF_BRICK_MAXVALUE
+};
+
+/* GLUSTER_HNDSK_PROGRAM for nersion 1 and 2*/
+enum gluster_prog_hndsk_procs {
+ GF_HNDSK_NULL = 0,
+ GF_HNDSK_SETVOLUME,
+ GF_HNDSK_GETSPEC,
+ GF_HNDSK_PING,
+ GF_HNDSK_SET_LK_VER,
+ GF_HNDSK_EVENT_NOTIFY,
+ GF_HNDSK_MAXVALUE
+};
+
+/* GLUSTER_PMAP_PROGRAM */
+enum gf_pmap_procnum {
+ GF_PMAP_NULL = 0,
+ GF_PMAP_PORTBYBRICK,
+ GF_PMAP_BRICKBYPORT,
+ GF_PMAP_SIGNUP,
+ GF_PMAP_SIGNIN,
+ GF_PMAP_SIGNOUT,
+ GF_PMAP_MAXVALUE
+};
+
+/* GD_BRICK_PROGRAM */
+enum glusterd_brick_procnum {
+ GLUSTERD_BRICK_NULL = 0,
+ GLUSTERD_BRICK_TERMINATE,
+ GLUSTERD_BRICK_XLATOR_INFO,
+ GLUSTERD_BRICK_XLATOR_HEAL,
+ GLUSTERD_BRICK_OP,
+ GLUSTERD_BRICK_MAXVALUE
+};
+
+/* "rpc/rpc-lib/src/protocol-common.h" line 174 of 228 */
+enum glusterd_brick_2_procnum {
+ GLUSTERD_2_BRICK_NULL, /* 0 */
+ GLUSTERD_2_BRICK_TERMINATE,
+ GLUSTERD_2_BRICK_XLATOR_INFO,
+ GLUSTERD_2_BRICK_XLATOR_OP,
+ GLUSTERD_2_BRICK_STATUS,
+ GLUSTERD_2_BRICK_OP,
+ GLUSTERD_2_BRICK_XLATOR_DEFRAG,
+ GLUSTERD_2_NODE_PROFILE,
+ GLUSTERD_2_NODE_STATUS,
+ GLUSTERD_2_BRICK_MAXVALUE,
+};
+
+
+/* GLUSTER_CBK_PROGRAM */
+enum gf_cbk_procnum {
+ GF_CBK_NULL = 0,
+ GF_CBK_FETCHSPEC,
+ GF_CBK_INO_FLUSH,
+ GF_CBK_MAXVALUE,
+
+};
+
+enum gf_fop_procnum {
+ GFS3_OP_NULL = 0,
+ GFS3_OP_STAT,
+ GFS3_OP_READLINK,
+ GFS3_OP_MKNOD,
+ GFS3_OP_MKDIR,
+ GFS3_OP_UNLINK,
+ GFS3_OP_RMDIR,
+ GFS3_OP_SYMLINK,
+ GFS3_OP_RENAME,
+ GFS3_OP_LINK,
+ GFS3_OP_TRUNCATE,
+ GFS3_OP_OPEN,
+ GFS3_OP_READ,
+ GFS3_OP_WRITE,
+ GFS3_OP_STATFS,
+ GFS3_OP_FLUSH,
+ GFS3_OP_FSYNC,
+ GFS3_OP_SETXATTR,
+ GFS3_OP_GETXATTR,
+ GFS3_OP_REMOVEXATTR,
+ GFS3_OP_OPENDIR,
+ GFS3_OP_FSYNCDIR,
+ GFS3_OP_ACCESS,
+ GFS3_OP_CREATE,
+ GFS3_OP_FTRUNCATE,
+ GFS3_OP_FSTAT,
+ GFS3_OP_LK,
+ GFS3_OP_LOOKUP,
+ GFS3_OP_READDIR,
+ GFS3_OP_INODELK,
+ GFS3_OP_FINODELK,
+ GFS3_OP_ENTRYLK,
+ GFS3_OP_FENTRYLK,
+ GFS3_OP_XATTROP,
+ GFS3_OP_FXATTROP,
+ GFS3_OP_FGETXATTR,
+ GFS3_OP_FSETXATTR,
+ GFS3_OP_RCHECKSUM,
+ GFS3_OP_SETATTR,
+ GFS3_OP_FSETATTR,
+ GFS3_OP_READDIRP,
+ GFS3_OP_RELEASE,
+ GFS3_OP_RELEASEDIR,
+ GFS3_OP_MAXVALUE
+};
+
+/* dir-entry types from libglusterfs/src/compat.h */
+enum gluster_entry_types {
+ DT_UNKNOWN = 0,
+ DT_FIFO = 1,
+ DT_CHR = 2,
+ DT_DIR = 4,
+ DT_BLK = 6,
+ DT_REG = 8,
+ DT_LNK = 10,
+ DT_SOCK = 12,
+ DT_WHT = 14
+};
+
+
+/* LOCKING operators come from libglusterfs/src/glusterfs.h */
+
+/* based on original enum glusterfs_lk_cmds_t */
+enum gluster_lk_cmds {
+ GF_LK_GETLK = 0,
+ GF_LK_SETLK,
+ GF_LK_SETLKW,
+ GF_LK_RESLK_LCK,
+ GF_LK_RESLK_LCKW,
+ GF_LK_RESLK_UNLCK,
+ GF_LK_GETLK_FD
+};
+
+/* based on original enum glusterfs_lk_types_t */
+enum gluster_lk_types {
+ GF_LK_F_RDLCK = 0,
+ GF_LK_F_WRLCK,
+ GF_LK_F_UNLCK,
+ GF_LK_EOL
+};
+
+/* based on enum glusterd_op_ from xlators/mgmt/glusterd/src/glusterd.h */
+enum glusterd_ops {
+ GD_OP_NONE = 0,
+ GD_OP_CREATE_VOLUME,
+ GD_OP_START_BRICK,
+ GD_OP_STOP_BRICK,
+ GD_OP_DELETE_VOLUME,
+ GD_OP_START_VOLUME,
+ GD_OP_STOP_VOLUME,
+ GD_OP_DEFRAG_VOLUME,
+ GD_OP_ADD_BRICK,
+ GD_OP_REMOVE_BRICK,
+ GD_OP_REPLACE_BRICK,
+ GD_OP_SET_VOLUME,
+ GD_OP_RESET_VOLUME,
+ GD_OP_SYNC_VOLUME,
+ GD_OP_LOG_ROTATE,
+ GD_OP_GSYNC_SET,
+ GD_OP_PROFILE_VOLUME,
+ GD_OP_QUOTA,
+ GD_OP_STATUS_VOLUME,
+ GD_OP_REBALANCE,
+ GD_OP_HEAL_VOLUME,
+ GD_OP_STATEDUMP_VOLUME,
+ GD_OP_LIST_VOLUME,
+ GD_OP_CLEARLOCKS_VOLUME,
+ GD_OP_DEFRAG_BRICK_VOLUME,
+ GD_OP_MAX
+};
+
+extern int
+gluster_rpc_dissect_dict(proto_tree *tree, tvbuff_t *tvb,
+ int hfindex, int offset);
+
+extern int
+gluster_dissect_common_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree);
+
+#endif /* __PACKET_GLUSTER_H__ */
diff --git a/epan/dissectors/packet-gluster_cli.c b/epan/dissectors/packet-gluster_cli.c
new file mode 100644
index 0000000..fe8032b
--- /dev/null
+++ b/epan/dissectors/packet-gluster_cli.c
@@ -0,0 +1,576 @@
+/* packet-gluster_cli.c
+ * Routines for Gluster CLI dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_gluster_cli = -1;
+
+/* programs and procedures */
+static gint hf_gluster_cli_proc = -1;
+static gint hf_gluster_cli_2_proc = -1;
+static gint hf_gluster_dict = -1;
+static gint hf_gluster_path = -1;
+static gint hf_gluster_lazy = -1;
+static gint hf_gluster_label = -1;
+static gint hf_gluster_unused = -1;
+static gint hf_gluster_wd= -1;
+static gint hf_gluster_op_errstr= -1;
+static gint hf_gluster_hostname = -1;
+static gint hf_gluster_port = -1;
+static gint hf_gluster_flags = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_gluster_cli = -1;
+
+/* CLI Operations */
+
+static int
+gluster_cli_2_common_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_common_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* errstr= NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset,
+ &errstr);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_probe_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* hostname = NULL;
+ gchar* errstr = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset,
+ &hostname);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset,
+ &errstr);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_probe_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* hostname = NULL;
+
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_deprobe_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* hostname = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_deprobe_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* hostname = NULL;
+
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_flags, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_fsm_log_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* name = NULL;
+
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_wd, offset, &name);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_getwd_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* wd = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_wd, offset, &wd);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_getwd_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_unused, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_mount_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* label = NULL;
+
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_label, offset, &label);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_mount_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* path = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_path, offset, &path);
+
+ return offset;
+}
+
+static int
+gluster_cli_2_umount_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* path = NULL;
+
+ offset = dissect_rpc_uint32(tvb, tree,hf_gluster_lazy, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_path, offset, &path);
+
+ return offset;
+}
+
+/* procedures for GLUSTER_CLI_PROGRAM */
+static const vsff gluster_cli_proc[] = {
+ { GLUSTER_CLI_NULL, "GLUSTER_CLI_NULL", NULL, NULL },
+ { GLUSTER_CLI_PROBE, "GLUSTER_CLI_PROBE", NULL, NULL },
+ { GLUSTER_CLI_DEPROBE, "GLUSTER_CLI_DEPROBE", NULL, NULL },
+ { GLUSTER_CLI_LIST_FRIENDS, "GLUSTER_CLI_LIST_FRIENDS", NULL, NULL },
+ { GLUSTER_CLI_CREATE_VOLUME, "GLUSTER_CLI_CREATE_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_GET_VOLUME, "GLUSTER_CLI_GET_VOLUME", NULL, NULL },
+ {
+ GLUSTER_CLI_GET_NEXT_VOLUME, "GLUSTER_CLI_GET_NEXT_VOLUME",
+ NULL, NULL
+ },
+ { GLUSTER_CLI_DELETE_VOLUME, "GLUSTER_CLI_DELETE_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_START_VOLUME, "GLUSTER_CLI_START_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_STOP_VOLUME, "GLUSTER_CLI_STOP_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_RENAME_VOLUME, "GLUSTER_CLI_RENAME_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_DEFRAG_VOLUME, "GLUSTER_CLI_DEFRAG_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_SET_VOLUME, "GLUSTER_CLI_SET_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_ADD_BRICK, "GLUSTER_CLI_ADD_BRICK", NULL, NULL },
+ { GLUSTER_CLI_REMOVE_BRICK, "GLUSTER_CLI_REMOVE_BRICK", NULL, NULL },
+ { GLUSTER_CLI_REPLACE_BRICK, "GLUSTER_CLI_REPLACE_BRICK", NULL, NULL },
+ { GLUSTER_CLI_LOG_FILENAME, "GLUSTER_CLI_LOG_FILENAME", NULL, NULL },
+ { GLUSTER_CLI_LOG_LOCATE, "GLUSTER_CLI_LOG_LOCATE", NULL, NULL },
+ { GLUSTER_CLI_LOG_ROTATE, "GLUSTER_CLI_LOG_ROTATE", NULL, NULL },
+ { GLUSTER_CLI_GETSPEC, "GLUSTER_CLI_GETSPEC", NULL, NULL },
+ {
+ GLUSTER_CLI_PMAP_PORTBYBRICK, "GLUSTER_CLI_PMAP_PORTBYBRICK",
+ NULL , NULL
+ },
+ { GLUSTER_CLI_SYNC_VOLUME, "GLUSTER_CLI_SYNC_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_RESET_VOLUME, "GLUSTER_CLI_RESET_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_FSM_LOG, "GLUSTER_CLI_FSM_LOG", NULL, NULL },
+ { GLUSTER_CLI_GSYNC_SET, "GLUSTER_CLI_GSYNC_SET", NULL, NULL },
+ {
+ GLUSTER_CLI_PROFILE_VOLUME, "GLUSTER_CLI_PROFILE_VOLUME",
+ NULL, NULL
+ },
+ { GLUSTER_CLI_QUOTA, "GLUSTER_CLI_QUOTA", NULL, NULL },
+ { GLUSTER_CLI_TOP_VOLUME, "GLUSTER_CLI_TOP_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_GETWD, "GLUSTER_CLI_GETWD", NULL, NULL },
+ { GLUSTER_CLI_LOG_LEVEL, "GLUSTER_CLI_LOG_LEVEL", NULL, NULL },
+ { GLUSTER_CLI_STATUS_VOLUME, "GLUSTER_CLI_STATUS_VOLUME", NULL, NULL },
+ { GLUSTER_CLI_MOUNT, "GLUSTER_CLI_MOUNT", NULL, NULL },
+ { GLUSTER_CLI_UMOUNT, "GLUSTER_CLI_UMOUNT", NULL, NULL },
+ { GLUSTER_CLI_HEAL_VOLUME, "GLUSTER_CLI_HEAL_VOLUME", NULL, NULL },
+ {
+ GLUSTER_CLI_STATEDUMP_VOLUME, "GLUSTER_CLI_STATEDUMP_VOLUME",
+ NULL, NULL
+ },
+ { GLUSTER_CLI_MAXVALUE, "GLUSTER_CLI_MAXVALUE", NULL, NULL },
+ { 0, NULL, NULL, NULL }
+};
+
+/* procedures for GLUSTER_CLI_PROGRAM version 2*/
+static const vsff gluster_cli_2_proc[] = {
+ {
+ GLUSTER_CLI_2_NULL, "GLUSTER_CLI_NULL",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_PROBE, "GLUSTER_CLI_PROBE",
+ gluster_cli_2_probe_call, gluster_cli_2_probe_reply
+ },
+ {
+ GLUSTER_CLI_2_DEPROBE, "GLUSTER_CLI_DEPROBE",
+ gluster_cli_2_deprobe_call, gluster_cli_2_deprobe_reply
+ },
+ {
+ GLUSTER_CLI_2_LIST_FRIENDS, "GLUSTER_CLI_LIST_FRIENDS",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_CREATE_VOLUME, "GLUSTER_CLI_CREATE_VOLUME" ,
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_GET_VOLUME, "GLUSTER_CLI_GET_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_GET_NEXT_VOLUME, "GLUSTER_CLI_GET_NEXT_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_DELETE_VOLUME, "GLUSTER_CLI_DELETE_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_START_VOLUME, "GLUSTER_CLI_START_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_STOP_VOLUME, "GLUSTER_CLI_STOP_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_RENAME_VOLUME, "GLUSTER_CLI_RENAME_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_DEFRAG_VOLUME, "GLUSTER_CLI_DEFRAG_VOLUME" ,
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_SET_VOLUME, "GLUSTER_CLI_SET_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_ADD_BRICK, "GLUSTER_CLI_ADD_BRICK",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_REMOVE_BRICK, "GLUSTER_CLI_REMOVE_BRICK",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_REPLACE_BRICK, "GLUSTER_CLI_REPLACE_BRICK",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_LOG_ROTATE, "GLUSTER_CLI_LOG_ROTATE",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_GETSPEC, "GLUSTER_CLI_GETSPEC",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_PMAP_PORTBYBRICK, "GLUSTER_CLI_PMAP_PORTBYBRICK",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_SYNC_VOLUME, "GLUSTER_CLI_SYNC_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_RESET_VOLUME, "GLUSTER_CLI_RESET_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_FSM_LOG, "GLUSTER_CLI_FSM_LOG",
+ gluster_cli_2_fsm_log_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_GSYNC_SET, "GLUSTER_CLI_GSYNC_SET",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_PROFILE_VOLUME, "GLUSTER_CLI_PROFILE_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_QUOTA, "GLUSTER_CLI_QUOTA",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_TOP_VOLUME, "GLUSTER_CLI_TOP_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_GETWD, "GLUSTER_CLI_GETWD",
+ gluster_cli_2_getwd_call, gluster_cli_2_getwd_reply
+ },
+ {
+ GLUSTER_CLI_2_STATUS_VOLUME, "GLUSTER_CLI_STATUS_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_STATUS_ALL, "GLUSTER_CLI_STATUS_ALL",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_MOUNT, "GLUSTER_CLI_MOUNT",
+ gluster_cli_2_mount_call, gluster_cli_2_mount_reply
+ },
+ {
+ GLUSTER_CLI_2_UMOUNT, "GLUSTER_CLI_UMOUNT",
+ gluster_cli_2_umount_call, gluster_dissect_common_reply
+ },
+ {
+ GLUSTER_CLI_2_HEAL_VOLUME, "GLUSTER_CLI_HEAL_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_STATEDUMP_VOLUME, "GLUSTER_CLI_STATEDUMP_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_LIST_VOLUME, "GLUSTER_CLI_LIST_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_CLRLOCKS_VOLUME, " GLUSTER_CLI_CLRLOCKS_VOLUME",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ {
+ GLUSTER_CLI_2_MAXVALUE, "GLUSTER_CLI_MAXVALUE",
+ gluster_cli_2_common_call, gluster_cli_2_common_reply
+ },
+ { 0, NULL , NULL, NULL}
+};
+
+
+static const value_string gluster_cli_proc_vals[] = {
+ { GLUSTER_CLI_NULL, "GLUSTER_CLI_NULL" },
+ { GLUSTER_CLI_PROBE, "GLUSTER_CLI_PROBE" },
+ { GLUSTER_CLI_DEPROBE, "GLUSTER_CLI_DEPROBE" },
+ { GLUSTER_CLI_LIST_FRIENDS, "GLUSTER_CLI_LIST_FRIENDS" },
+ { GLUSTER_CLI_CREATE_VOLUME, "GLUSTER_CLI_CREATE_VOLUME" },
+ { GLUSTER_CLI_GET_VOLUME, "GLUSTER_CLI_GET_VOLUME" },
+ { GLUSTER_CLI_GET_NEXT_VOLUME, "GLUSTER_CLI_GET_NEXT_VOLUME" },
+ { GLUSTER_CLI_DELETE_VOLUME, "GLUSTER_CLI_DELETE_VOLUME" },
+ { GLUSTER_CLI_START_VOLUME, "GLUSTER_CLI_START_VOLUME" },
+ { GLUSTER_CLI_STOP_VOLUME, "GLUSTER_CLI_STOP_VOLUME" },
+ { GLUSTER_CLI_RENAME_VOLUME, "GLUSTER_CLI_RENAME_VOLUME" },
+ { GLUSTER_CLI_DEFRAG_VOLUME, "GLUSTER_CLI_DEFRAG_VOLUME" },
+ { GLUSTER_CLI_SET_VOLUME, "GLUSTER_CLI_SET_VOLUME" },
+ { GLUSTER_CLI_ADD_BRICK, "GLUSTER_CLI_ADD_BRICK" },
+ { GLUSTER_CLI_REMOVE_BRICK, "GLUSTER_CLI_REMOVE_BRICK" },
+ { GLUSTER_CLI_REPLACE_BRICK, "GLUSTER_CLI_REPLACE_BRICK" },
+ { GLUSTER_CLI_LOG_FILENAME, "GLUSTER_CLI_LOG_FILENAME" },
+ { GLUSTER_CLI_LOG_LOCATE, "GLUSTER_CLI_LOG_LOCATE" },
+ { GLUSTER_CLI_LOG_ROTATE, "GLUSTER_CLI_LOG_ROTATE" },
+ { GLUSTER_CLI_GETSPEC, "GLUSTER_CLI_GETSPEC" },
+ { GLUSTER_CLI_PMAP_PORTBYBRICK, "GLUSTER_CLI_PMAP_PORTBYBRICK" },
+ { GLUSTER_CLI_SYNC_VOLUME, "GLUSTER_CLI_SYNC_VOLUME" },
+ { GLUSTER_CLI_RESET_VOLUME, "GLUSTER_CLI_RESET_VOLUME" },
+ { GLUSTER_CLI_FSM_LOG, "GLUSTER_CLI_FSM_LOG" },
+ { GLUSTER_CLI_GSYNC_SET, "GLUSTER_CLI_GSYNC_SET" },
+ { GLUSTER_CLI_PROFILE_VOLUME, "GLUSTER_CLI_PROFILE_VOLUME" },
+ { GLUSTER_CLI_QUOTA, "GLUSTER_CLI_QUOTA" },
+ { GLUSTER_CLI_TOP_VOLUME, "GLUSTER_CLI_TOP_VOLUME" },
+ { GLUSTER_CLI_GETWD, "GLUSTER_CLI_GETWD" },
+ { GLUSTER_CLI_LOG_LEVEL, "GLUSTER_CLI_LOG_LEVEL" },
+ { GLUSTER_CLI_STATUS_VOLUME, "GLUSTER_CLI_STATUS_VOLUME" },
+ { GLUSTER_CLI_MOUNT, "GLUSTER_CLI_MOUNT" },
+ { GLUSTER_CLI_UMOUNT, "GLUSTER_CLI_UMOUNT" },
+ { GLUSTER_CLI_HEAL_VOLUME, "GLUSTER_CLI_HEAL_VOLUME" },
+ { GLUSTER_CLI_STATEDUMP_VOLUME, "GLUSTER_CLI_STATEDUMP_VOLUME" },
+ { GLUSTER_CLI_MAXVALUE, "GLUSTER_CLI_MAXVALUE" },
+ { 0, NULL }
+};
+
+static const value_string gluster_cli_2_proc_vals[] = {
+ { GLUSTER_CLI_2_NULL, "GLUSTER_CLI_NULL" },
+ { GLUSTER_CLI_2_PROBE, "GLUSTER_CLI_PROBE" },
+ { GLUSTER_CLI_2_DEPROBE, "GLUSTER_CLI_DEPROBE" },
+ { GLUSTER_CLI_2_LIST_FRIENDS, "GLUSTER_CLI_LIST_FRIENDS" },
+ { GLUSTER_CLI_2_CREATE_VOLUME, "GLUSTER_CLI_CREATE_VOLUME" },
+ { GLUSTER_CLI_2_GET_VOLUME, "GLUSTER_CLI_GET_VOLUME" },
+ { GLUSTER_CLI_2_GET_NEXT_VOLUME, "GLUSTER_CLI_GET_NEXT_VOLUME" },
+ { GLUSTER_CLI_2_DELETE_VOLUME, "GLUSTER_CLI_DELETE_VOLUME" },
+ { GLUSTER_CLI_2_START_VOLUME, "GLUSTER_CLI_START_VOLUME" },
+ { GLUSTER_CLI_2_STOP_VOLUME, "GLUSTER_CLI_STOP_VOLUME" },
+ { GLUSTER_CLI_2_RENAME_VOLUME, "GLUSTER_CLI_RENAME_VOLUME" },
+ { GLUSTER_CLI_2_DEFRAG_VOLUME, "GLUSTER_CLI_DEFRAG_VOLUME" },
+ { GLUSTER_CLI_2_SET_VOLUME, "GLUSTER_CLI_SET_VOLUME" },
+ { GLUSTER_CLI_2_ADD_BRICK, "GLUSTER_CLI_ADD_BRICK" },
+ { GLUSTER_CLI_2_REMOVE_BRICK, "GLUSTER_CLI_REMOVE_BRICK" },
+ { GLUSTER_CLI_2_REPLACE_BRICK, "GLUSTER_CLI_REPLACE_BRICK" },
+ { GLUSTER_CLI_2_LOG_ROTATE, "GLUSTER_CLI_LOG_ROTATE" },
+ { GLUSTER_CLI_2_GETSPEC, "GLUSTER_CLI_GETSPEC" },
+ { GLUSTER_CLI_2_PMAP_PORTBYBRICK, "GLUSTER_CLI_PMAP_PORTBYBRICK" },
+ { GLUSTER_CLI_2_SYNC_VOLUME, "GLUSTER_CLI_SYNC_VOLUME" },
+ { GLUSTER_CLI_2_RESET_VOLUME, "GLUSTER_CLI_RESET_VOLUME" },
+ { GLUSTER_CLI_2_FSM_LOG, "GLUSTER_CLI_FSM_LOG" },
+ { GLUSTER_CLI_2_GSYNC_SET, "GLUSTER_CLI_GSYNC_SET" },
+ { GLUSTER_CLI_2_PROFILE_VOLUME, "GLUSTER_CLI_PROFILE_VOLUME" },
+ { GLUSTER_CLI_2_QUOTA, "GLUSTER_CLI_QUOTA" },
+ { GLUSTER_CLI_2_TOP_VOLUME, "GLUSTER_CLI_TOP_VOLUME" },
+ { GLUSTER_CLI_2_GETWD, "GLUSTER_CLI_GETWD" },
+ { GLUSTER_CLI_2_STATUS_VOLUME, "GLUSTER_CLI_STATUS_VOLUME" },
+ { GLUSTER_CLI_2_STATUS_ALL, "GLUSTER_CLI_STATUS_ALL" },
+ { GLUSTER_CLI_2_MOUNT, "GLUSTER_CLI_MOUNT" },
+ { GLUSTER_CLI_2_UMOUNT, "GLUSTER_CLI_UMOUNT" },
+ { GLUSTER_CLI_2_HEAL_VOLUME, "GLUSTER_CLI_HEAL_VOLUME" },
+ { GLUSTER_CLI_2_STATEDUMP_VOLUME, "GLUSTER_CLI_STATEDUMP_VOLUME" },
+ { GLUSTER_CLI_2_LIST_VOLUME, "GLUSTER_CLI_LIST_VOLUME"},
+ { GLUSTER_CLI_2_CLRLOCKS_VOLUME, " GLUSTER_CLI_CLRLOCKS_VOLUME" },
+ { GLUSTER_CLI_2_MAXVALUE, "GLUSTER_CLI_MAXVALUE" },
+ { 0, NULL }
+};
+
+void
+proto_register_gluster_cli(void)
+{
+ /* Setup list of header fields See Section 1.6.1 for details */
+ static hf_register_info hf[] = {
+ /* programs */
+ { &hf_gluster_cli_proc,
+ { "Gluster CLI", "gluster.cli", FT_UINT32, BASE_DEC,
+ VALS(gluster_cli_proc_vals), 0, NULL, HFILL }
+ },
+ { &hf_gluster_cli_2_proc,
+ { "Gluster CLI", "gluster.cli", FT_UINT32, BASE_DEC,
+ VALS(gluster_cli_2_proc_vals), 0, NULL, HFILL }
+ },
+ { &hf_gluster_dict,
+ { "Dict", "gluster.dict", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_path,
+ { "Path", "gluster.path", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_lazy,
+ { "lazy", "gluster.lazy", FT_UINT32, BASE_OCT,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_label,
+ { "Label", "gluster.label", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_unused,
+ { "Unused", "gluster.unused", FT_UINT32, BASE_OCT,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_wd,
+ { "Path", "gluster.wd", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_op_errstr,
+ { "Error", "gluster.op_errstr", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hostname,
+ { "Hostname", "gluster.hostname", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_port,
+ { "Port", "gluster.port", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_flags,
+ { "Flags", "gluster.flag", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ }
+ };
+
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gluster_cli
+ };
+
+ /* Register the protocol name and description */
+ proto_gluster_cli = proto_register_protocol("Gluster CLI",
+ "Gluster CLI", "gluster-cli");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_gluster_cli, hf, array_length(hf));
+}
+
+void
+proto_reg_handoff_gluster_cli(void)
+{
+ rpc_init_prog(proto_gluster_cli, GLUSTER_CLI_PROGRAM, ett_gluster_cli);
+ rpc_init_proc_table(GLUSTER_CLI_PROGRAM, 1, gluster_cli_proc,
+ hf_gluster_cli_proc);
+ rpc_init_proc_table(GLUSTER_CLI_PROGRAM, 2, gluster_cli_2_proc,
+ hf_gluster_cli_2_proc);
+}
+
diff --git a/epan/dissectors/packet-gluster_dump.c b/epan/dissectors/packet-gluster_dump.c
new file mode 100644
index 0000000..00091b4
--- /dev/null
+++ b/epan/dissectors/packet-gluster_dump.c
@@ -0,0 +1,180 @@
+/* packet-gluster_dump.c
+ * Routines for Gluster DUMP dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_gluster_dump = -1;
+
+/* programs and procedures */
+static gint hf_gluster_dump_proc = -1;
+
+/* fields used by multiple programs/procedures */
+static gint hf_gluster_gfsid = -1;
+static gint hf_gluster_progname = -1;
+static gint hf_gluster_prognum = -1;
+static gint hf_gluster_progver = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_gluster_dump = -1;
+static gint ett_gluster_dump_detail = -1;
+
+/* Based on rpc/rpc-lib/src/rpc-common.c, but xdr encoding/decoding is broken.
+ * The structure in rpc/rpc-lib/src/xdr-common.h lists 2x unit64_t, but to
+ * encode/decode, xdr_u_quad_t() is used (which is uint32_t).
+ */
+static int
+gluster_dump_reply_detail(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
+{
+ proto_item *detail_item;
+ proto_tree *detail_tree;
+ gchar *progname = NULL;
+
+ detail_item = proto_tree_add_text(tree, tvb, offset, -1,
+ "Available Progam: ");
+ detail_tree = proto_item_add_subtree(detail_item,
+ ett_gluster_dump_detail);
+
+ /* progname */
+ offset = dissect_rpc_string(tvb, detail_tree, hf_gluster_progname,
+ offset, &progname);
+ if (tree)
+ proto_item_append_text(detail_item, "%s", progname);
+
+ /* prognumber (marked as uint64) */
+ offset = dissect_rpc_uint64(tvb, detail_tree, hf_gluster_prognum,
+ offset);
+ /* progversion (marked as uint64) */
+ offset = dissect_rpc_uint64(tvb, detail_tree, hf_gluster_progver,
+ offset);
+
+ return offset;
+}
+
+static int
+gluster_dump_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
+{
+ offset = dissect_rpc_uint64(tvb, tree, hf_gluster_gfsid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ offset = dissect_rpc_list(tvb, pinfo, tree, offset,
+ gluster_dump_reply_detail);
+
+ return offset;
+}
+
+/* DUMP request */
+static int
+gluster_dump_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
+{
+ offset = dissect_rpc_uint64(tvb, tree, hf_gluster_gfsid, offset);
+
+ return offset;
+}
+
+/* procedures for GLUSTER_DUMP_PROGRAM */
+static const vsff gluster_dump_proc[] = {
+ { 0, "NULL", NULL, NULL },
+ { GF_DUMP_DUMP, "DUMP", gluster_dump_call, gluster_dump_reply },
+ { 0, NULL, NULL, NULL }
+};
+static const value_string gluster_dump_proc_vals[] = {
+ { 0, "NULL" },
+ { GF_DUMP_DUMP, "DUMP" },
+ { 0, NULL }
+};
+
+void
+proto_register_gluster_dump(void)
+{
+ /* Setup list of header fields See Section 1.6.1 for details */
+ static hf_register_info hf[] = {
+ /* programs */
+ { &hf_gluster_dump_proc,
+ { "Gluster DUMP", "gluster.dump", FT_UINT32, BASE_DEC,
+ VALS(gluster_dump_proc_vals), 0, NULL, HFILL }
+ },
+ { &hf_gluster_progname,
+ { "Program Name", "gluster.dump.progname", FT_STRING,
+ BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_prognum,
+ { "Program Number", "gluster.dump.prognum",
+ FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_progver,
+ { "Program Version", "gluster.dump.progver",
+ FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_gfsid,
+ { "GFS ID", "gluster.gfsid", FT_UINT64,
+ BASE_HEX, NULL, 0, NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gluster_dump,
+ &ett_gluster_dump_detail
+ };
+
+ proto_gluster_dump = proto_register_protocol("Gluster Dump",
+ "Gluster Dump", "gluster-dump");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_gluster_dump, hf, array_length(hf));
+}
+
+void
+proto_reg_handoff_gluster_dump(void)
+{
+ rpc_init_prog(proto_gluster_dump, GLUSTER_DUMP_PROGRAM,
+ ett_gluster_dump);
+ rpc_init_proc_table(GLUSTER_DUMP_PROGRAM, 1, gluster_dump_proc,
+ hf_gluster_dump_proc);
+}
+
diff --git a/epan/dissectors/packet-gluster_gd_mgmt.c b/epan/dissectors/packet-gluster_gd_mgmt.c
new file mode 100644
index 0000000..d0e3a3a
--- /dev/null
+++ b/epan/dissectors/packet-gluster_gd_mgmt.c
@@ -0,0 +1,656 @@
+/* packet-gluster_gd_mgmt.c
+ * Routines for Gluster Daemon Management dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_glusterd = -1;
+static gint proto_gd_mgmt = -1;
+static gint proto_gd_brick = -1;
+/* programs and procedures */
+static gint hf_gd_mgmt_proc = -1;
+static gint hf_gd_mgmt_2_proc = -1;
+static gint hf_gd_mgmt_brick_2_proc = -1;
+
+/* fields used by multiple programs/procedures */
+static gint hf_gluster_dict = -1;
+static gint hf_gluster_op = -1;
+static gint hf_gluster_op_errstr = -1;
+static gint hf_gluster_uuid = -1;
+static gint hf_gluster_hostname = -1;
+static gint hf_gluster_port = -1;
+static gint hf_gluster_vols = -1;
+static gint hf_gluster_buf = -1;
+static gint hf_gluster_name = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_gd_mgmt = -1;
+static gint ett_gd_brick = -1;
+
+/* the UUID is the same as a GlusterFS GFID, except its encoded per byte */
+static int
+gluster_gd_mgmt_dissect_uuid(tvbuff_t *tvb, proto_tree *tree, int hfindex, int offset)
+{
+ if (tree) {
+ proto_item *gfid_item;
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ gfid_item = proto_tree_add_text(tree, tvb, offset, 16 * 4, "%s: ", hfinfo->name);
+
+ /* 4 bytes */
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ /* 6 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+ } else
+ offset += 16 * 4;
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_probe_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *hostname = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_probe_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *hostname = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_friend_add_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *hostname = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_friend_add_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *hostname = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hostname, offset, &hostname);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_vols, offset);
+
+ return offset;
+}
+
+/* gluster_gd_mgmt_cluster_lock_reply is used for LOCK and UNLOCK */
+static int
+gluster_gd_mgmt_cluster_lock_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/* gluster_gd_mgmt_cluster_lock_call is used for LOCK and UNLOCK */
+static int
+gluster_gd_mgmt_cluster_lock_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_stage_op_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *errstr = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset, &errstr);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_stage_op_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_commit_op_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *errstr = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_buf, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset, &errstr);
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_commit_op_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_buf, offset);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_friend_update_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+gluster_gd_mgmt_friend_update_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_vols, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_port, offset);
+
+ return offset;
+}
+
+/* Below procedure is used for version 2 */
+static int
+glusterd_mgmt_2_cluster_lock_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/* glusterd__mgmt_2_cluster_lock_call is used for LOCK and UNLOCK */
+static int
+glusterd_mgmt_2_cluster_lock_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+
+ return offset;
+}
+
+static int
+glusterd_mgmt_2_stage_op_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *errstr = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset, &errstr);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterd_mgmt_2_stage_op_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterd_mgmt_2_commit_op_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *errstr = NULL;
+
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_buf, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset, &errstr);
+
+ return offset;
+}
+
+static int
+glusterd_mgmt_2_commit_op_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_gd_mgmt_dissect_uuid(tvb, tree, hf_gluster_uuid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_buf, offset);
+
+ return offset;
+}
+
+/* Brick management common function */
+
+static int
+glusterd_brick_2_common_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *errstr = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_op_errstr, offset, &errstr);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterd_brick_2_common_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *name = NULL;
+
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_name, offset, &name);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_dict, offset);
+
+ return offset;
+}
+
+/*
+ * GD_MGMT_PROGRAM
+ * - xlators/mgmt/glusterd/src/glusterd-handler.c: "GlusterD svc mgmt"
+ * - xlators/mgmt/glusterd/src/glusterd-rpc-ops.c: "glusterd clnt mgmt"
+ */
+static const vsff gd_mgmt_proc[] = {
+ { GD_MGMT_NULL, "NULL", NULL, NULL},
+ {
+ GD_MGMT_PROBE_QUERY, "GD_MGMT_PROBE_QUERY",
+ gluster_gd_mgmt_probe_call, gluster_gd_mgmt_probe_reply
+ },
+ {
+ GD_MGMT_FRIEND_ADD, "GD_MGMT_FRIEND_ADD",
+ gluster_gd_mgmt_friend_add_call, gluster_gd_mgmt_friend_add_reply
+ },
+ {
+ GD_MGMT_CLUSTER_LOCK, "GD_MGMT_CLUSTER_LOCK",
+ gluster_gd_mgmt_cluster_lock_call, gluster_gd_mgmt_cluster_lock_reply
+ },
+ {
+ GD_MGMT_CLUSTER_UNLOCK, "GD_MGMT_CLUSTER_UNLOCK",
+ /* UNLOCK seems to be the same a LOCK, re-use the function */
+ gluster_gd_mgmt_cluster_lock_call, gluster_gd_mgmt_cluster_lock_reply
+ },
+ {
+ GD_MGMT_STAGE_OP, "GD_MGMT_STAGE_OP",
+ gluster_gd_mgmt_stage_op_call, gluster_gd_mgmt_stage_op_reply
+ },
+ {
+ GD_MGMT_COMMIT_OP, "GD_MGMT_COMMIT_OP",
+ gluster_gd_mgmt_commit_op_call, gluster_gd_mgmt_commit_op_reply
+ },
+ { GD_MGMT_FRIEND_REMOVE, "GD_MGMT_FRIEND_REMOVE", NULL, NULL},
+ {
+ GD_MGMT_FRIEND_UPDATE, "GD_MGMT_FRIEND_UPDATE",
+ gluster_gd_mgmt_friend_update_call, gluster_gd_mgmt_friend_update_reply
+ },
+ { GD_MGMT_CLI_PROBE, "GD_MGMT_CLI_PROBE", NULL, NULL},
+ { GD_MGMT_CLI_DEPROBE, "GD_MGMT_CLI_DEPROBE", NULL, NULL},
+ { GD_MGMT_CLI_LIST_FRIENDS, "GD_MGMT_CLI_LIST_FRIENDS", NULL, NULL},
+ { GD_MGMT_CLI_CREATE_VOLUME, "GD_MGMT_CLI_CREATE_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_GET_VOLUME, "GD_MGMT_CLI_GET_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_DELETE_VOLUME, "GD_MGMT_CLI_DELETE_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_START_VOLUME, "GD_MGMT_CLI_START_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_STOP_VOLUME, "GD_MGMT_CLI_STOP_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_RENAME_VOLUME, "GD_MGMT_CLI_RENAME_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_DEFRAG_VOLUME, "GD_MGMT_CLI_DEFRAG_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_SET_VOLUME, "GD_MGMT_CLI_DEFRAG_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_ADD_BRICK, "GD_MGMT_CLI_ADD_BRICK", NULL, NULL},
+ { GD_MGMT_CLI_REMOVE_BRICK, "GD_MGMT_CLI_REMOVE_BRICK", NULL, NULL},
+ { GD_MGMT_CLI_REPLACE_BRICK, "GD_MGMT_CLI_REPLACE_BRICK", NULL, NULL},
+ { GD_MGMT_CLI_LOG_FILENAME, "GD_MGMT_CLI_LOG_FILENAME", NULL, NULL},
+ { GD_MGMT_CLI_LOG_LOCATE, "GD_MGMT_CLI_LOG_LOCATE", NULL, NULL},
+ { GD_MGMT_CLI_LOG_ROTATE, "GD_MGMT_CLI_LOG_ROTATE", NULL, NULL},
+ { GD_MGMT_CLI_SYNC_VOLUME, "GD_MGMT_CLI_SYNC_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_RESET_VOLUME, "GD_MGMT_CLI_RESET_VOLUME", NULL, NULL},
+ { GD_MGMT_CLI_FSM_LOG, "GD_MGMT_CLI_FSM_LOG", NULL, NULL},
+ { GD_MGMT_CLI_GSYNC_SET, "GD_MGMT_CLI_GSYNC_SET", NULL, NULL},
+ { GD_MGMT_CLI_PROFILE_VOLUME, "GD_MGMT_CLI_PROFILE_VOLUME", NULL, NULL},
+ { GD_MGMT_BRICK_OP, "BRICK_OP", NULL, NULL},
+ { GD_MGMT_CLI_LOG_LEVEL, "GD_MGMT_CLI_LOG_LEVEL", NULL, NULL},
+ { GD_MGMT_CLI_STATUS_VOLUME, "GD_MGMT_CLI_STATUS_VOLUME", NULL, NULL},
+ { GD_MGMT_MAXVALUE, "GD_MGMT_MAXVALUE", NULL, NULL},
+ { 0, NULL, NULL, NULL}
+};
+
+static const vsff gd_mgmt_2_proc[] = {
+ { GLUSTERD_MGMT_2_NULL, "NULL", NULL, NULL},
+ {
+ GLUSTERD_MGMT_2_CLUSTER_LOCK, "GD_MGMT_CLUSTER_LOCK",
+ glusterd_mgmt_2_cluster_lock_call, glusterd_mgmt_2_cluster_lock_reply
+ },
+ {
+ GLUSTERD_MGMT_2_CLUSTER_UNLOCK, "GD_MGMT_CLUSTER_UNLOCK",
+ /* UNLOCK seems to be the same a LOCK, re-use the function */
+ glusterd_mgmt_2_cluster_lock_call, glusterd_mgmt_2_cluster_lock_reply
+ },
+ {
+ GLUSTERD_MGMT_2_STAGE_OP, "GD_MGMT_STAGE_OP",
+ glusterd_mgmt_2_stage_op_call, glusterd_mgmt_2_stage_op_reply
+ },
+ {
+ GLUSTERD_MGMT_2_COMMIT_OP, "GD_MGMT_COMMIT_OP",
+ glusterd_mgmt_2_commit_op_call, glusterd_mgmt_2_commit_op_reply
+ },
+ { GLUSTERD_MGMT_2_MAXVALUE, "GD_MGMT_MAXVALUE", NULL, NULL},
+ { 0, NULL, NULL, NULL}
+};
+
+static const vsff gd_mgmt_brick_2_proc[] = {
+ { GLUSTERD_2_BRICK_NULL, "GLUSTERD_2_BRICK_NULL", NULL , NULL }, /* 0 */
+ {
+ GLUSTERD_2_BRICK_TERMINATE, "GLUSTERD_2_BRICK_TERMINATE",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_BRICK_XLATOR_INFO, "GLUSTERD_2_BRICK_XLATOR_INFO",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_BRICK_XLATOR_OP, "GLUSTERD_2_BRICK_XLATOR_OP" ,
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_BRICK_STATUS, "GLUSTERD_2_BRICK_STATUS",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_BRICK_OP, "GLUSTERD_2_BRICK_OP",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_BRICK_XLATOR_DEFRAG, "GLUSTERD_2_BRICK_XLATOR_DEFRAG",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_NODE_PROFILE, "GLUSTERD_2_NODE_PROFILE",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ {
+ GLUSTERD_2_NODE_STATUS, "GLUSTERD_2_NODE_PROFILE",
+ glusterd_brick_2_common_call, glusterd_brick_2_common_reply
+ },
+ { GLUSTERD_2_BRICK_MAXVALUE, "GLUSTERD_2_BRICK_MAXVALUE", NULL, NULL },
+ { 0, NULL, NULL, NULL }
+};
+
+static const value_string gd_mgmt_proc_vals[] = {
+ { GD_MGMT_NULL, "NULL" },
+ { GD_MGMT_PROBE_QUERY, "GD_MGMT_PROBE_QUERY" },
+ { GD_MGMT_FRIEND_ADD, "GD_MGMT_FRIEND_ADD" },
+ { GD_MGMT_CLUSTER_LOCK, "GD_MGMT_CLUSTER_LOCK" },
+ { GD_MGMT_CLUSTER_UNLOCK, "GD_MGMT_CLUSTER_UNLOCK" },
+ { GD_MGMT_STAGE_OP, "GD_MGMT_STAGE_OP" },
+ { GD_MGMT_COMMIT_OP, "GD_MGMT_COMMIT_OP" },
+ { GD_MGMT_FRIEND_REMOVE, "GD_MGMT_FRIEND_REMOVE" },
+ { GD_MGMT_FRIEND_UPDATE, "GD_MGMT_FRIEND_UPDATE" },
+ { GD_MGMT_CLI_PROBE, "GD_MGMT_CLI_PROBE" },
+ { GD_MGMT_CLI_DEPROBE, "GD_MGMT_CLI_DEPROBE" },
+ { GD_MGMT_CLI_LIST_FRIENDS, "GD_MGMT_CLI_LIST_FRIENDS" },
+ { GD_MGMT_CLI_CREATE_VOLUME, "GD_MGMT_CLI_CREATE_VOLUME" },
+ { GD_MGMT_CLI_GET_VOLUME, "GD_MGMT_CLI_GET_VOLUME" },
+ { GD_MGMT_CLI_DELETE_VOLUME, "GD_MGMT_CLI_DELETE_VOLUME" },
+ { GD_MGMT_CLI_START_VOLUME, "GD_MGMT_CLI_START_VOLUME" },
+ { GD_MGMT_CLI_STOP_VOLUME, "GD_MGMT_CLI_STOP_VOLUME" },
+ { GD_MGMT_CLI_RENAME_VOLUME, "GD_MGMT_CLI_RENAME_VOLUME" },
+ { GD_MGMT_CLI_DEFRAG_VOLUME, "GD_MGMT_CLI_DEFRAG_VOLUME" },
+ { GD_MGMT_CLI_SET_VOLUME, "GD_MGMT_CLI_DEFRAG_VOLUME" },
+ { GD_MGMT_CLI_ADD_BRICK, "GD_MGMT_CLI_ADD_BRICK" },
+ { GD_MGMT_CLI_REMOVE_BRICK, "GD_MGMT_CLI_REMOVE_BRICK" },
+ { GD_MGMT_CLI_REPLACE_BRICK, "GD_MGMT_CLI_REPLACE_BRICK" },
+ { GD_MGMT_CLI_LOG_FILENAME, "GD_MGMT_CLI_LOG_FILENAME" },
+ { GD_MGMT_CLI_LOG_LOCATE, "GD_MGMT_CLI_LOG_LOCATE" },
+ { GD_MGMT_CLI_LOG_ROTATE, "GD_MGMT_CLI_LOG_ROTATE" },
+ { GD_MGMT_CLI_SYNC_VOLUME, "GD_MGMT_CLI_SYNC_VOLUME" },
+ { GD_MGMT_CLI_RESET_VOLUME, "GD_MGMT_CLI_RESET_VOLUME" },
+ { GD_MGMT_CLI_FSM_LOG, "GD_MGMT_CLI_FSM_LOG" },
+ { GD_MGMT_CLI_GSYNC_SET, "GD_MGMT_CLI_GSYNC_SET" },
+ { GD_MGMT_CLI_PROFILE_VOLUME, "GD_MGMT_CLI_PROFILE_VOLUME" },
+ { GD_MGMT_BRICK_OP, "BRICK_OP" },
+ { GD_MGMT_CLI_LOG_LEVEL, "GD_MGMT_CLI_LOG_LEVEL" },
+ { GD_MGMT_CLI_STATUS_VOLUME, "GD_MGMT_CLI_STATUS_VOLUME" },
+ { GD_MGMT_MAXVALUE, "GD_MGMT_MAXVALUE" },
+ { 0, NULL }
+};
+
+static const value_string gd_mgmt_2_proc_vals[] = {
+ { GLUSTERD_MGMT_2_NULL , "GLUSTERD_MGMT_NULL" },
+ { GLUSTERD_MGMT_2_CLUSTER_LOCK, "GLUSTERD_MGMT_CLUSTER_LOCK" },
+ { GLUSTERD_MGMT_2_CLUSTER_UNLOCK, "GLUSTERD_MGMT_CLUSTER_UNLOCK" },
+ { GLUSTERD_MGMT_2_STAGE_OP, "GLUSTERD_MGMT_STAGE_OP"},
+ { GLUSTERD_MGMT_2_COMMIT_OP, " GLUSTERD_MGMT_COMMIT_OP"},
+ { GLUSTERD_MGMT_2_MAXVALUE, "GLUSTERD_MGMT_MAXVALUE" },
+ { 0, NULL }
+};
+
+static const value_string gd_mgmt_brick_2_proc_vals[] = {
+ { GLUSTERD_2_BRICK_NULL,"GLUSTERD_2_BRICK_NULL" }, /* 0 */
+ { GLUSTERD_2_BRICK_TERMINATE, "GLUSTERD_2_BRICK_TERMINATE" },
+ { GLUSTERD_2_BRICK_XLATOR_INFO, "GLUSTERD_2_BRICK_XLATOR_INFO" },
+ { GLUSTERD_2_BRICK_XLATOR_OP, "GLUSTERD_2_BRICK_XLATOR_OP" },
+ { GLUSTERD_2_BRICK_STATUS, "GLUSTERD_2_BRICK_STATUS" },
+ { GLUSTERD_2_BRICK_OP, "GLUSTERD_2_BRICK_OP" },
+ { GLUSTERD_2_BRICK_XLATOR_DEFRAG, "GLUSTERD_2_BRICK_XLATOR_DEFRAG" },
+ { GLUSTERD_2_NODE_PROFILE, "GLUSTERD_2_NODE_PROFILE" },
+ { GLUSTERD_2_NODE_STATUS, "GLUSTERD_2_NODE_PROFILE" },
+ { GLUSTERD_2_BRICK_MAXVALUE, "GLUSTERD_2_BRICK_MAXVALUE" },
+ { 0, NULL }
+};
+
+static const value_string glusterd_op_vals[] = {
+ { GD_OP_NONE, "NONE" },
+ { GD_OP_CREATE_VOLUME, "CREATE_VOLUME" },
+ { GD_OP_START_BRICK, "START_BRICK" },
+ { GD_OP_STOP_BRICK, "STOP_BRICK" },
+ { GD_OP_DELETE_VOLUME, "DELETE_VOLUME" },
+ { GD_OP_START_VOLUME, "START_VOLUME" },
+ { GD_OP_STOP_VOLUME, "STOP_VOLUME" },
+ { GD_OP_DEFRAG_VOLUME, "DEFRAG_VOLUME" },
+ { GD_OP_ADD_BRICK, "ADD_BRICK" },
+ { GD_OP_REMOVE_BRICK, "REMOVE_BRICK" },
+ { GD_OP_REPLACE_BRICK, "REPLACE_BRICK" },
+ { GD_OP_SET_VOLUME, "SET_VOLUME" },
+ { GD_OP_RESET_VOLUME, "RESET_VOLUME" },
+ { GD_OP_SYNC_VOLUME, "SYNC_VOLUME" },
+ { GD_OP_LOG_ROTATE, "LOG_ROTATE" },
+ { GD_OP_GSYNC_SET, "GSYNC_SET" },
+ { GD_OP_PROFILE_VOLUME, "PROFILE_VOLUME" },
+ { GD_OP_QUOTA, "QUOTA" },
+ { GD_OP_STATUS_VOLUME, "STATUS_VOLUME" },
+ { GD_OP_REBALANCE, "REBALANCE" },
+ { GD_OP_HEAL_VOLUME, "HEAL_VOLUME" },
+ { GD_OP_STATEDUMP_VOLUME, "STATEDUMP_VOLUME" },
+ { GD_OP_LIST_VOLUME, "LIST_VOLUME" },
+ { GD_OP_CLEARLOCKS_VOLUME, "CLEARLOCKS_VOLUME" },
+ { GD_OP_DEFRAG_BRICK_VOLUME, "DEFRAG_BRICK_VOLUME" },
+ { 0, NULL }
+};
+void
+proto_register_gluster_gd_mgmt(void)
+{
+ /* Setup list of header fields See Section 1.6.1 for details */
+ static hf_register_info hf[] = {
+ /* programs */
+ { &hf_gd_mgmt_proc,
+ { "Gluster Daemon Management", "glusterd.mgmt",
+ FT_UINT32, BASE_DEC, VALS(gd_mgmt_proc_vals),
+ 0, NULL, HFILL }
+ },
+ { &hf_gd_mgmt_2_proc,
+ { "Gluster Daemon Management", "glusterd.mgmt",
+ FT_UINT32, BASE_DEC, VALS(gd_mgmt_2_proc_vals),
+ 0, NULL, HFILL }
+ },
+ { &hf_gd_mgmt_brick_2_proc,
+ { "Gluster Daemon Management", "glusterd.mgmt",
+ FT_UINT32, BASE_DEC, VALS(gd_mgmt_brick_2_proc_vals),
+ 0, NULL, HFILL }
+ },
+
+ { &hf_gluster_dict,
+ { "Dict", "gluster.dict", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_op,
+ { "Operation", "gluster.op", FT_UINT32, BASE_DEC,
+ VALS(glusterd_op_vals), 0, NULL, HFILL }
+ },
+ { &hf_gluster_op_errstr,
+ { "Error", "gluster.op_errstr", FT_STRING,
+ BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_uuid,
+ { "UUID", "gluster.uuid", FT_BYTES,
+ BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hostname,
+ { "Hostname", "gluster.hostname", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_port,
+ { "Port", "gluster.port", FT_INT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_vols,
+ { "Volumes", "gluster.vols", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_buf,
+ { "Buffer", "gluster.buffer", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_name,
+ { "Name", "gluster.name", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gd_mgmt,
+ &ett_gd_brick
+ };
+
+ /* Register the protocol name and description */
+ proto_glusterd = proto_register_protocol("Gluster Daemon", "GlusterD",
+ "glusterd");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_glusterd, hf, array_length(hf));
+
+ proto_gd_mgmt = proto_register_protocol("Gluster Daemon Management",
+ "GlusterD Management", "gd-mgmt");
+ proto_gd_brick = proto_register_protocol("Gluster Daemon Brick",
+ "GlusterD Brick", "gd-brick");
+}
+
+void
+proto_reg_handoff_gluster_gd_mgmt(void)
+{
+ rpc_init_prog(proto_gd_mgmt, GD_MGMT_PROGRAM, ett_gd_mgmt);
+ rpc_init_proc_table(GD_MGMT_PROGRAM, 1, gd_mgmt_proc, hf_gd_mgmt_proc);
+ rpc_init_proc_table(GD_MGMT_PROGRAM, 2, gd_mgmt_2_proc, hf_gd_mgmt_2_proc);
+
+ rpc_init_prog(proto_gd_brick, GD_BRICK_PROGRAM, ett_gd_brick);
+ rpc_init_proc_table(GD_BRICK_PROGRAM, 2, gd_mgmt_brick_2_proc, hf_gd_mgmt_brick_2_proc);
+}
+
diff --git a/epan/dissectors/packet-gluster_hndsk.c b/epan/dissectors/packet-gluster_hndsk.c
new file mode 100644
index 0000000..8624f48
--- /dev/null
+++ b/epan/dissectors/packet-gluster_hndsk.c
@@ -0,0 +1,323 @@
+/* packet-gluster_hndsk.c
+ * Routines for Gluster Handshake dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_gluster_cbk = -1;
+static gint proto_gluster_hndsk = -1;
+
+/* programs and procedures */
+static gint hf_gluster_cbk_proc = -1;
+static gint hf_gluster_hndsk_proc = -1;
+static gint hf_gluster_hndsk_dict = -1;
+static gint hf_gluster_hndsk_spec = -1; /* GETSPEC Reply */
+static gint hf_gluster_hndsk_key = -1; /* GETSPEC Call */
+static gint hf_gluster_hndsk_event_op = -1; /* EVENT NOTIFY call */
+static gint hf_gluster_hndsk_uid = -1; /* LOCK VERSION*/
+static gint hf_gluster_hndsk_lk_ver= -1;
+static gint hf_gluster_hndsk_flags = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_gluster_cbk = -1;
+static gint ett_gluster_hndsk = -1;
+
+/* procedures for GLUSTER_HNDSK_PROGRAM */
+static int
+gluster_hndsk_setvolume_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_setvolume_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_setvolume_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_setvolume_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_getspec_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* spec = NULL;
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_spec, offset, &spec);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_getspec_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint flags;
+ gchar *key = NULL;
+ flags = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint_format(tree, hf_gluster_hndsk_flags, tvb, offset, 4, flags, "Flags: 0x%02x", flags);
+ offset += 4;
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_key, offset, &key);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_set_lk_ver_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint32(tvb, tree,hf_gluster_hndsk_lk_ver, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_set_lk_ver_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* uid = NULL;
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_uid, offset, &uid);
+ offset = dissect_rpc_uint32(tvb, tree,hf_gluster_hndsk_lk_ver, offset);
+ return offset;
+}
+
+static int
+gluster_hndsk_2_event_notify_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_hndsk_event_op, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+/* In rpc/xdr/src/glusterfs3-xdr.c. xdr_gf_event_notify_rsp */
+
+static int
+gluster_hndsk_2_event_notify_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict, offset);
+ return offset;
+}
+
+static const vsff gluster_hndsk_proc[] = {
+ { GF_HNDSK_NULL, "NULL", NULL, NULL },
+ {
+ GF_HNDSK_SETVOLUME, "SETVOLUME",
+ gluster_hndsk_setvolume_call, gluster_hndsk_setvolume_reply
+ },
+ { GF_HNDSK_GETSPEC, "GETSPEC", NULL, NULL },
+ { GF_HNDSK_PING, "PING", NULL, gluster_dissect_common_reply },
+ { 0, NULL, NULL, NULL }
+};
+
+static const vsff gluster_hndsk_2_proc[] = {
+ { GF_HNDSK_NULL, "NULL", NULL, NULL },
+ {
+ GF_HNDSK_SETVOLUME, "SETVOLUME",
+ gluster_hndsk_2_setvolume_call, gluster_hndsk_2_setvolume_reply
+ },
+ {
+ GF_HNDSK_GETSPEC, "GETSPEC",
+ gluster_hndsk_2_getspec_call, gluster_hndsk_2_getspec_reply
+ },
+ { GF_HNDSK_PING, "PING", NULL, gluster_dissect_common_reply },
+ {
+ GF_HNDSK_SET_LK_VER,"LOCK VERSION",
+ gluster_hndsk_2_set_lk_ver_call, gluster_hndsk_2_set_lk_ver_reply
+ },
+ {
+ GF_HNDSK_EVENT_NOTIFY, "EVENTNOTIFY",
+ gluster_hndsk_2_event_notify_call, gluster_hndsk_2_event_notify_reply
+ },
+ { 0, NULL, NULL, NULL }
+};
+
+
+static const value_string gluster_hndsk_proc_vals[] = {
+ { GF_HNDSK_NULL, "NULL" },
+ { GF_HNDSK_SETVOLUME, "DUMP" },
+ { GF_HNDSK_GETSPEC, "GETSPEC" },
+ { GF_HNDSK_PING, "PING" },
+ { GF_HNDSK_SET_LK_VER,"LOCK VERSION" },
+ { GF_HNDSK_EVENT_NOTIFY, "EVENTNOTIFY" },
+ { 0, NULL }
+};
+
+void
+proto_register_gluster_hndsk(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_gluster_hndsk_proc,
+ { "GlusterFS Handshake", "gluster.hndsk", FT_UINT32,
+ BASE_DEC, VALS(gluster_hndsk_proc_vals), 0,
+ NULL, HFILL }
+ },
+ /* fields used by Gluster Handshake */
+ { &hf_gluster_hndsk_dict,
+ { "Dict", "gluster.hndsk.dict", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ /* For Gluster handshake event notify */
+ { &hf_gluster_hndsk_event_op,
+ { "Event Op", "gluster.hndsk.event_notify_op", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hndsk_key,
+ { "Key", "gluster.hndsk.getspec.key", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hndsk_spec,
+ /* FIXME: rename spec to something clearer */
+ { "Spec", "gluster.hndsk.getspec", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ /* For hand shake set_lk_ver */
+ { &hf_gluster_hndsk_uid,
+ { "Name", "gluster.hndsk.uid", FT_STRING, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hndsk_lk_ver,
+ { "Event Op", "gluster.hndsk.lk_ver", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_hndsk_flags,
+ { "Flags", "gluster.hndsk.flags", FT_UINT32, BASE_OCT,
+ NULL, 0, NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gluster_hndsk
+ };
+
+ /* Register the protocol name and description */
+ proto_gluster_hndsk = proto_register_protocol("GlusterFS Handshake",
+ "GlusterFS Handshake", "gluster-hndsk");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_gluster_hndsk, hf, array_length(hf));
+
+}
+
+void
+proto_reg_handoff_gluster_hndsk(void)
+{
+ rpc_init_prog(proto_gluster_hndsk, GLUSTER_HNDSK_PROGRAM,
+ ett_gluster_hndsk);
+ rpc_init_proc_table(GLUSTER_HNDSK_PROGRAM, 1, gluster_hndsk_proc,
+ hf_gluster_hndsk_proc);
+ rpc_init_proc_table(GLUSTER_HNDSK_PROGRAM, 2, gluster_hndsk_2_proc,
+ hf_gluster_hndsk_proc);
+}
+
+/* Legacy GlusterFS Callback procedures, they don't contain any data. */
+static const vsff gluster_cbk_proc[] = {
+ { GF_CBK_NULL, "NULL", NULL, NULL },
+ { GF_CBK_FETCHSPEC, "FETCHSPEC", NULL, NULL },
+ { GF_CBK_INO_FLUSH, "INO_FLUSH", NULL, NULL },
+ { 0, NULL, NULL, NULL }
+};
+static const value_string gluster_cbk_proc_vals[] = {
+ { GF_CBK_NULL, "NULL" },
+ { GF_CBK_FETCHSPEC, "FETCHSPEC" },
+ { GF_CBK_INO_FLUSH, "INO_FLUSH" },
+ { 0, NULL }
+};
+
+void
+proto_register_gluster_cbk(void)
+{
+ /* Setup list of header fields See Section 1.6.1 for details */
+ static hf_register_info hf[] = {
+ /* programs */
+ { &hf_gluster_cbk_proc,
+ { "GlusterFS Callback", "gluster.cbk", FT_UINT32,
+ BASE_DEC, VALS(gluster_cbk_proc_vals), 0, NULL,
+ HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gluster_cbk
+ };
+
+ /* Register the protocol name and description */
+ proto_gluster_cbk = proto_register_protocol("GlusterFS Callback",
+ "GlusterFS Callback", "gluster-cbk");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_gluster_cbk, hf, array_length(hf));
+}
+
+void
+proto_reg_handoff_gluster_cbk(void)
+{
+ rpc_init_prog(proto_gluster_cbk, GLUSTER_CBK_PROGRAM, ett_gluster_cbk);
+ rpc_init_proc_table(GLUSTER_CBK_PROGRAM, 1, gluster_cbk_proc,
+ hf_gluster_cbk_proc);
+}
+
diff --git a/epan/dissectors/packet-gluster_pmap.c b/epan/dissectors/packet-gluster_pmap.c
new file mode 100644
index 0000000..c157c3e
--- /dev/null
+++ b/epan/dissectors/packet-gluster_pmap.c
@@ -0,0 +1,151 @@
+/* packet-gluster_pmap.c
+ * Routines for Gluster Portmapper dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_gluster_pmap = -1;
+
+/* programs and procedures */
+static gint hf_gluster_pmap_proc = -1;
+
+/* fields used by multiple programs/procedures */
+static gint hf_gluster_brick = -1;
+static gint hf_gluster_brick_status = -1;
+static gint hf_gluster_brick_port = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_gluster_pmap = -1;
+
+/* PMAP PORTBYBRICK */
+static int
+gluster_pmap_portbybrick_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_brick_status, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_brick_port, offset);
+
+ return offset;
+}
+
+static int
+gluster_pmap_portbybrick_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *brick = NULL;
+ offset = dissect_rpc_string(tvb, tree, hf_gluster_brick, offset,
+ &brick);
+ return offset;
+}
+
+/* GLUSTER_PMAP_PROGRAM from xlators/mgmt/glusterd/src/glusterd-pmap.c */
+static const vsff gluster_pmap_proc[] = {
+ { GF_PMAP_NULL, "NULL", NULL, NULL },
+ {
+ GF_PMAP_PORTBYBRICK, "PORTBYBRICK",
+ gluster_pmap_portbybrick_call, gluster_pmap_portbybrick_reply
+ },
+ { GF_PMAP_BRICKBYPORT, "BRICKBYPORT", NULL, NULL },
+ { GF_PMAP_SIGNIN, "SIGNIN", NULL, NULL },
+ { GF_PMAP_SIGNOUT, "SIGNOUT", NULL, NULL },
+ { GF_PMAP_SIGNUP, "SIGNUP", NULL, NULL },
+ { 0, NULL, NULL, NULL }
+};
+static const value_string gluster_pmap_proc_vals[] = {
+ { GF_PMAP_NULL, "NULL" },
+ { GF_PMAP_PORTBYBRICK, "PORTBYBRICK" },
+ { GF_PMAP_BRICKBYPORT, "BRICKBYPORT" },
+ { GF_PMAP_SIGNIN, "SIGNIN" },
+ { GF_PMAP_SIGNOUT, "SIGNOUT" },
+ { GF_PMAP_SIGNUP, "SIGNUP" },
+ { 0, NULL }
+};
+
+void
+proto_register_gluster_pmap(void)
+{
+ /* Setup list of header fields See Section 1.6.1 for details */
+ static hf_register_info hf[] = {
+ /* programs */
+ { &hf_gluster_pmap_proc,
+ { "Gluster Portmap", "gluster.pmap", FT_UINT32,
+ BASE_DEC, VALS(gluster_pmap_proc_vals), 0,
+ NULL, HFILL }
+ },
+ { &hf_gluster_brick,
+ { "Brick", "gluster.brick", FT_STRINGZ, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_brick_status,
+ { "Status", "gluster.brick.status", FT_INT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_gluster_brick_port,
+ { "Port", "gluster.brick.port", FT_INT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_gluster_pmap
+ };
+
+ proto_gluster_pmap = proto_register_protocol("Gluster Portmap",
+ "Gluster Portmap", "gluster-pmap");
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_gluster_pmap, hf, array_length(hf));
+}
+
+void
+proto_reg_handoff_gluster_pmap(void)
+{
+ rpc_init_prog(proto_gluster_pmap, GLUSTER_PMAP_PROGRAM,
+ ett_gluster_pmap);
+ rpc_init_proc_table(GLUSTER_PMAP_PROGRAM, 1, gluster_pmap_proc,
+ hf_gluster_pmap_proc);
+}
+
diff --git a/epan/dissectors/packet-glusterfs.c b/epan/dissectors/packet-glusterfs.c
new file mode 100644
index 0000000..e9504d1
--- /dev/null
+++ b/epan/dissectors/packet-glusterfs.c
@@ -0,0 +1,2704 @@
+/* packet-glusterfs.c
+ * Routines for GlusterFS dissection
+ * Copyright 2012, Niels de Vos <ndevos@redhat.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * References to source files point in general to the glusterfs sources.
+ * There is currently no RFC or other document where the protocol is
+ * completely described. The glusterfs sources can be found at:
+ * - http://git.gluster.com/?p=glusterfs.git
+ * - https://github.com/gluster/glusterfs
+ *
+ * The coding-style is roughly the same as the one use in the Linux kernel,
+ * see http://www.kernel.org/doc/Documentation/CodingStyle.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/tfs.h>
+
+#include "packet-rpc.h"
+#include "packet-gluster.h"
+
+/* Initialize the protocol and registered fields */
+static gint proto_glusterfs = -1;
+
+/* programs and procedures */
+static gint hf_glusterfs_proc = -1;
+
+/* fields used by multiple programs/procedures */
+static gint hf_gluster_op_ret = -1;
+static gint hf_gluster_op_errno = -1;
+
+/* GlusterFS specific */
+static gint hf_glusterfs_gfid = -1;
+static gint hf_glusterfs_pargfid = -1;
+static gint hf_glusterfs_oldgfid = -1;
+static gint hf_glusterfs_newgfid = -1;
+static gint hf_glusterfs_path = -1;
+static gint hf_glusterfs_bname = -1;
+static gint hf_glusterfs_dict = -1;
+static gint hf_glusterfs_fd = -1;
+static gint hf_glusterfs_offset = -1;
+static gint hf_glusterfs_size = -1;
+static gint hf_glusterfs_volume = -1;
+static gint hf_glusterfs_cmd = -1;
+static gint hf_glusterfs_type = -1;
+static gint hf_glusterfs_entries = -1;
+static gint hf_glusterfs_xflags = -1;
+static gint hf_glusterfs_linkname = -1;
+static gint hf_glusterfs_umask = -1;
+static gint hf_glusterfs_mask = -1;
+static gint hf_glusterfs_name = -1;
+static gint hf_glusterfs_namelen = -1;
+
+/* flags passed on to OPEN, CREATE etc.*/
+static gint hf_glusterfs_flags = -1;
+static gint hf_glusterfs_flags_rdonly = -1;
+static gint hf_glusterfs_flags_wronly = -1;
+static gint hf_glusterfs_flags_rdwr = -1;
+static gint hf_glusterfs_flags_accmode = -1;
+static gint hf_glusterfs_flags_append = -1;
+static gint hf_glusterfs_flags_async = -1;
+static gint hf_glusterfs_flags_cloexec = -1;
+static gint hf_glusterfs_flags_creat = -1;
+static gint hf_glusterfs_flags_direct = -1;
+static gint hf_glusterfs_flags_directory = -1;
+static gint hf_glusterfs_flags_excl = -1;
+static gint hf_glusterfs_flags_largefile = -1;
+static gint hf_glusterfs_flags_noatime = -1;
+static gint hf_glusterfs_flags_noctty = -1;
+static gint hf_glusterfs_flags_nofollow = -1;
+static gint hf_glusterfs_flags_nonblock = -1;
+static gint hf_glusterfs_flags_ndelay = -1;
+static gint hf_glusterfs_flags_sync = -1;
+static gint hf_glusterfs_flags_trunc = -1;
+
+/* access modes */
+static gint hf_glusterfs_mode = -1;
+static gint hf_glusterfs_mode_suid = -1;
+static gint hf_glusterfs_mode_sgid = -1;
+static gint hf_glusterfs_mode_svtx = -1;
+static gint hf_glusterfs_mode_rusr = -1;
+static gint hf_glusterfs_mode_wusr = -1;
+static gint hf_glusterfs_mode_xusr = -1;
+static gint hf_glusterfs_mode_rgrp = -1;
+static gint hf_glusterfs_mode_wgrp = -1;
+static gint hf_glusterfs_mode_xgrp = -1;
+static gint hf_glusterfs_mode_roth = -1;
+static gint hf_glusterfs_mode_woth = -1;
+static gint hf_glusterfs_mode_xoth = -1;
+
+/* dir-entry */
+static gint hf_glusterfs_entry_ino = -1;
+static gint hf_glusterfs_entry_off = -1;
+static gint hf_glusterfs_entry_len = -1;
+static gint hf_glusterfs_entry_type = -1;
+static gint hf_glusterfs_entry_path = -1;
+
+/* gf_iatt */
+static gint hf_glusterfs_ia_ino = -1;
+static gint hf_glusterfs_ia_dev = -1;
+static gint hf_glusterfs_ia_mode = -1;
+static gint hf_glusterfs_ia_nlink = -1;
+static gint hf_glusterfs_ia_uid = -1;
+static gint hf_glusterfs_ia_gid = -1;
+static gint hf_glusterfs_ia_rdev = -1;
+static gint hf_glusterfs_ia_size = -1;
+static gint hf_glusterfs_ia_blksize = -1;
+static gint hf_glusterfs_ia_blocks = -1;
+static gint hf_glusterfs_ia_atime = -1;
+static gint hf_glusterfs_ia_atime_nsec = -1;
+static gint hf_glusterfs_ia_mtime = -1;
+static gint hf_glusterfs_ia_mtime_nsec = -1;
+static gint hf_glusterfs_ia_ctime = -1;
+static gint hf_glusterfs_ia_ctime_nsec = -1;
+
+/* gf_flock */
+static gint hf_glusterfs_flock_type = -1;
+static gint hf_glusterfs_flock_whence = -1;
+static gint hf_glusterfs_flock_start = -1;
+static gint hf_glusterfs_flock_len = -1;
+static gint hf_glusterfs_flock_pid = -1;
+static gint hf_glusterfs_flock_owner = -1;
+
+/* statfs */
+static gint hf_glusterfs_bsize = -1;
+static gint hf_glusterfs_frsize = -1;
+static gint hf_glusterfs_blocks = -1;
+static gint hf_glusterfs_bfree = -1;
+static gint hf_glusterfs_bavail = -1;
+static gint hf_glusterfs_files = -1;
+static gint hf_glusterfs_ffree = -1;
+static gint hf_glusterfs_favail = -1;
+static gint hf_glusterfs_id = -1;
+static gint hf_glusterfs_flag = -1;
+static gint hf_glusterfs_namemax = -1;
+
+static gint hf_glusterfs_setattr_valid = -1;
+
+/* Rename */
+static gint hf_glusterfs_oldbname = -1;
+static gint hf_glusterfs_newbname = -1;
+
+/* for FSYNCDIR */
+static gint hf_glusterfs_yncdir_data = -1;
+
+/* for entrylk */
+static gint hf_glusterfs_entrylk_namelen = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_glusterfs = -1;
+static gint ett_glusterfs_flags = -1;
+static gint ett_glusterfs_mode = -1;
+static gint ett_glusterfs_iatt = -1;
+static gint ett_glusterfs_entry = -1;
+static gint ett_glusterfs_flock = -1;
+static gint ett_gluster_dict = -1;
+static gint ett_gluster_dict_items = -1;
+
+/* function for dissecting and adding a GFID to the tree
+ *
+ * Show as the by Gluster displayed string format
+ * 00000000-0000-0000-0000-000000000001 (4-2-2-2-6 bytes).
+ */
+static int
+glusterfs_item_append_gfid(proto_item *gfid_item, tvbuff_t *tvb, int offset)
+{
+ /* 4 bytes */
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ /* 2 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ /* 6 bytes */
+ proto_item_append_text(gfid_item, "-%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+ proto_item_append_text(gfid_item, "%.2x", tvb_get_guint8(tvb, offset++));
+
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_gfid(proto_tree *tree, tvbuff_t *tvb, int hfindex, int offset)
+{
+ proto_item *gfid_item;
+
+ if (tree) {
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+
+ gfid_item = proto_tree_add_item(tree, hfindex, tvb, offset, 16, ENC_NA);
+ PROTO_ITEM_SET_HIDDEN(gfid_item);
+
+ gfid_item = proto_tree_add_text(tree, tvb, offset, 16, "%s: ", hfinfo->name);
+ offset = glusterfs_item_append_gfid(gfid_item, tvb, offset);
+ } else
+ offset += 16;
+
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_mode(proto_tree *tree, tvbuff_t *tvb, int hfindex, int offset)
+{
+ static const int *mode_bits[] = {
+ &hf_glusterfs_mode_suid,
+ &hf_glusterfs_mode_sgid,
+ &hf_glusterfs_mode_svtx,
+ &hf_glusterfs_mode_rusr,
+ &hf_glusterfs_mode_wusr,
+ &hf_glusterfs_mode_xusr,
+ &hf_glusterfs_mode_rgrp,
+ &hf_glusterfs_mode_wgrp,
+ &hf_glusterfs_mode_xgrp,
+ &hf_glusterfs_mode_roth,
+ &hf_glusterfs_mode_woth,
+ &hf_glusterfs_mode_xoth,
+ NULL
+ };
+
+ if (tree)
+ proto_tree_add_bitmask(tree, tvb, offset, hfindex, ett_glusterfs_mode, mode_bits, FALSE);
+
+ offset += 4;
+ return offset;
+}
+
+/*
+ * from rpc/xdr/src/glusterfs3-xdr.c:xdr_gf_iatt()
+ * FIXME: this may be inclomplete, different code-paths may require different
+ * encoding/decoding.
+ */
+static int
+glusterfs_rpc_dissect_gf_iatt(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ia_ino, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ia_dev, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_ia_mode, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_nlink, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_uid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_gid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ia_rdev, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ia_size, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_blksize, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ia_blocks, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_atime, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_atime_nsec, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_mtime, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_mtime_nsec, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_ctime, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_ia_ctime_nsec, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_gf_flock(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_type, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_whence, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flock_start, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flock_len, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_pid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flock_owner, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_gf_2_flock(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_type, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_whence, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flock_start, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flock_len, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_flock_pid, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ gboolean rdonly, accmode;
+ proto_item *flag_tree, *rdonly_item, *accmode_item;
+ header_field_info *rdonly_hf, *accmode_hf;
+
+ static const int *flag_bits[] = {
+ &hf_glusterfs_flags_wronly,
+ &hf_glusterfs_flags_rdwr,
+ &hf_glusterfs_flags_creat,
+ &hf_glusterfs_flags_excl,
+ &hf_glusterfs_flags_noctty,
+ &hf_glusterfs_flags_trunc,
+ &hf_glusterfs_flags_append,
+ &hf_glusterfs_flags_nonblock,
+ &hf_glusterfs_flags_ndelay,
+ &hf_glusterfs_flags_sync,
+ &hf_glusterfs_flags_async,
+ &hf_glusterfs_flags_direct,
+ &hf_glusterfs_flags_largefile,
+ &hf_glusterfs_flags_directory,
+ &hf_glusterfs_flags_nofollow,
+ &hf_glusterfs_flags_noatime,
+ &hf_glusterfs_flags_cloexec,
+ NULL
+ };
+
+ if (tree) {
+ flag_tree = proto_tree_add_bitmask(tree, tvb, offset, hf_glusterfs_flags, ett_glusterfs_flags, flag_bits, FALSE);
+
+ /* rdonly is TRUE only when no flags are set */
+ rdonly = (tvb_get_ntohl(tvb, offset) == 0);
+ rdonly_item = proto_tree_add_boolean(flag_tree, hf_glusterfs_flags_rdonly, tvb, offset, 4, rdonly);
+ rdonly_hf = proto_registrar_get_nth(hf_glusterfs_flags_rdonly);
+ /* show a static value of zero's, proto_tree_add_boolean() removes them */
+ proto_item_set_text(rdonly_item, "0000 0000 0000 0000 0000 0000 0000 0000 = %s: %s",
+ rdonly_hf->name, rdonly ? tfs_set_notset.true_string : tfs_set_notset.false_string);
+ PROTO_ITEM_SET_GENERATED(rdonly_item);
+ if (rdonly)
+ proto_item_append_text(flag_tree, ", %s", rdonly_hf->name);
+
+ /* hf_glusterfs_flags_accmode is TRUE if bits 0 and 1 are set */
+ accmode_hf = proto_registrar_get_nth(hf_glusterfs_flags_accmode);
+ accmode = ((tvb_get_ntohl(tvb, offset) & accmode_hf->bitmask) == accmode_hf->bitmask);
+ accmode_item = proto_tree_add_boolean(flag_tree, hf_glusterfs_flags_accmode, tvb, offset, 4, accmode);
+ PROTO_ITEM_SET_GENERATED(accmode_item);
+ if (accmode)
+ proto_item_append_text(flag_tree, ", %s", proto_registrar_get_nth(hf_glusterfs_flags_accmode)->name);
+ }
+
+ offset += 4;
+ return offset;
+}
+
+static int
+glusterfs_rpc_dissect_statfs(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_bsize, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_frsize, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_blocks, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_bfree, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_bavail, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_files, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_ffree, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_favail, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_id, offset);
+ /* FIXME: hf_glusterfs_flag are flags, see 'man 2 statvfs' */
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_flag, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_namemax, offset);
+
+ return offset;
+}
+
+/* function for dissecting and adding a gluster dict_t to the tree */
+int
+gluster_rpc_dissect_dict(proto_tree *tree, tvbuff_t *tvb, int hfindex, int offset)
+{
+ gchar *key, *value;
+ gint items, i, len, roundup, value_len, key_len;
+
+ proto_item *subtree_item;
+ proto_tree *subtree;
+
+ proto_item *dict_item;
+
+ /* create a subtree for all the items in the dict */
+ if (hfindex >= 0) {
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ subtree_item = proto_tree_add_text(tree, tvb, offset, -1, "%s", hfinfo->name);
+ } else {
+ subtree_item = proto_tree_add_text(tree, tvb, offset, -1, "<NAMELESS DICT STRUCTURE>");
+ }
+
+ subtree = proto_item_add_subtree(subtree_item, ett_gluster_dict);
+
+ len = tvb_get_ntohl(tvb, offset);
+ roundup = rpc_roundup(len) - len;
+ proto_tree_add_text(subtree, tvb, offset, 4, "[Size: %d (%d bytes inc. RPC-roundup)]", len, rpc_roundup(len));
+ offset += 4;
+
+ if (len == 0)
+ return offset;
+
+ items = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_text(subtree, tvb, offset, 4, "[Items: %d]", items);
+ offset += 4;
+
+ for (i = 0; i < items; i++) {
+ /* key_len is the length of the key without the terminating '\0' */
+ /* key_len = tvb_get_ntohl(tvb, offset) + 1; // will be read later */
+ offset += 4;
+ value_len = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+
+ /* read the key, '\0' terminated */
+ key = tvb_get_stringz(tvb, offset, &key_len);
+ if (tree)
+ dict_item = proto_tree_add_text(subtree, tvb, offset, -1, "%s: ", key);
+ offset += key_len;
+
+ /* read the value, possibly '\0' terminated */
+ value = tvb_get_string(tvb, offset, value_len);
+ if (tree) {
+ /* keys named "gfid-req" contain a GFID in hex */
+ if (value_len == 16 && !strncmp("gfid-req", key, 8))
+ glusterfs_item_append_gfid(dict_item, tvb, offset);
+ else
+ proto_item_append_text(dict_item, "%s", value);
+ }
+ offset += value_len;
+
+ g_free(key);
+ g_free(value);
+ }
+
+ if (roundup) {
+ if (tree)
+ proto_tree_add_text(subtree, tvb, offset, -1, "[RPC-roundup bytes: %d]", roundup);
+ offset += roundup;
+ }
+
+ return offset;
+}
+
+int
+gluster_dissect_common_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *errno_item;
+ guint op_errno;
+
+ offset = dissect_rpc_uint32(tvb, tree, hf_gluster_op_ret, offset);
+
+ if (tree) {
+ op_errno = tvb_get_ntohl(tvb, offset);
+ errno_item = proto_tree_add_int(tree, hf_gluster_op_errno, tvb,
+ offset, 4, op_errno);
+ proto_item_append_text(errno_item, " (%s)",
+ g_strerror(op_errno));
+ }
+
+ offset += 4;
+
+ return offset;
+}
+
+/*
+ * 372 if (!xdr_int (xdrs, &objp->op_ret))
+ * 373 return FALSE;
+ * 374 if (!xdr_int (xdrs, &objp->op_errno))
+ * 375 return FALSE;
+ * 376 if (!xdr_gf_iatt (xdrs, &objp->preparent))
+ * 377 return FALSE;
+ * 378 if (!xdr_gf_iatt (xdrs, &objp->postparent))
+ *
+ */
+static int
+glusterfs_gfs3_op_unlink_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ return offset;
+}
+
+/*
+ * 359 if (!xdr_opaque (xdrs, objp->pargfid, 16))
+ * 360 return FALSE;
+ * 361 if (!xdr_string (xdrs, &objp->path, ~0))
+ * 362 return FALSE;
+ * 363 if (!xdr_string (xdrs, &objp->bname, ~0))
+ * 364 return FALSE;
+ *
+ */
+static int
+glusterfs_gfs3_op_unlink_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* path = NULL;
+ gchar* bname = NULL;
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_statfs_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = glusterfs_rpc_dissect_statfs(tree, tvb, offset);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_statfs_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *path = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_flush_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_setxattr_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *path = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_opendir_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_opendir_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *path = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+
+ return offset;
+}
+
+/* rpc/xdr/src/glusterfs3-xdr.c:xdr_gfs3_create_rsp */
+static int
+glusterfs_gfs3_op_create_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ return offset;
+}
+
+/* rpc/xdr/src/glusterfs3-xdr.c:xdr_gfs3_create_req */
+static int
+glusterfs_gfs3_op_create_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *path = NULL;
+ gchar *bname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_mode, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_lookup_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_lookup_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *path = NULL;
+ gchar *bname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_inodelk_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *flock_item;
+ proto_tree *flock_tree;
+ gchar* path = NULL;
+ gchar* volume = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_cmd, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_type, offset);
+
+ flock_item = proto_tree_add_text(tree, tvb, offset, -1, "flock");
+ flock_tree = proto_item_add_subtree(flock_item, ett_glusterfs_flock);
+ offset = glusterfs_rpc_dissect_gf_flock(flock_tree, tvb, offset);
+
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_volume, offset, &volume);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_readdirp_entry(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *entry_item, *iatt_item;
+ proto_tree *entry_tree, *iatt_tree;
+ gchar* path = NULL;
+
+ entry_item = proto_tree_add_text(tree, tvb, offset, -1, "Entry");
+ entry_tree = proto_item_add_subtree(entry_item, ett_glusterfs_entry);
+
+ offset = dissect_rpc_uint64(tvb, entry_tree, hf_glusterfs_entry_ino, offset);
+ offset = dissect_rpc_uint64(tvb, entry_tree, hf_glusterfs_entry_off, offset);
+ offset = dissect_rpc_uint32(tvb, entry_tree, hf_glusterfs_entry_len, offset);
+ offset = dissect_rpc_uint32(tvb, entry_tree, hf_glusterfs_entry_type, offset);
+ offset = dissect_rpc_string(tvb, entry_tree, hf_glusterfs_entry_path, offset, &path);
+
+ proto_item_append_text(entry_item, " Path:%s", path);
+
+ iatt_item = proto_tree_add_text(entry_tree, tvb, offset, -1, "Stat");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ return offset;
+}
+
+
+/* details in xlators/storage/posix/src/posix.c:posix_fill_readdir() */
+static int
+glusterfs_gfs3_op_readdirp_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *errno_item;
+ guint op_errno;
+
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_entries, offset);
+
+ if (tree) {
+ op_errno = tvb_get_ntohl(tvb, offset);
+ errno_item = proto_tree_add_int(tree, hf_gluster_op_errno, tvb,
+ offset, 4, op_errno);
+ if (op_errno == 0)
+ proto_item_append_text(errno_item,
+ " (More READDIRP replies follow)");
+ else if (op_errno == 2 /* ENOENT */)
+ proto_item_append_text(errno_item,
+ " (Last READDIRP reply)");
+ }
+ offset += 4;
+
+ offset = dissect_rpc_list(tvb, pinfo, tree, offset,
+ glusterfs_gfs3_op_readdirp_entry);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_readdirp_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_offset, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_size, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_setattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "StatPre IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "StatPost IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_op_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+ gchar *path = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "stbuff IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: hf_glusterfs_setattr_valid is a flag
+ * see libglusterfs/src/xlator.h, #defines for GF_SET_ATTR_*
+ */
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_setattr_valid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+
+ return offset;
+}
+
+/*GlusterFS 3_3 fops */
+
+static int
+glusterfs_gfs3_3_op_stat_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+ return offset;
+
+}
+
+static int
+glusterfs_gfs3_3_op_stat_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ // FIXME: describe this better - gf_iatt (xdrs, &objp->stat
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat Buf");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_mknod_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_mknod_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+
+ gchar *bname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_offset, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_mode, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_umask, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_mkdir_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_mkdir_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *bname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_mode, offset);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_umask, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_readlink_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ gchar* path = NULL;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Buf IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_path, offset, &path);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_readlink_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_size, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_unlink_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_unlink_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint xflags;
+ gchar* bname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ xflags = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint_format(tree, hf_glusterfs_xflags, tvb, offset, 4, xflags, "Flags: 0%02o", xflags);
+ offset += 4;
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_rmdir_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_rmdir_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar* bname = NULL;
+ guint xflags;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ xflags = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint_format(tree, hf_glusterfs_xflags, tvb, offset, 4, xflags, "Flags: 0%02o", xflags);
+ offset += 4;
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_symlink_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *bname = NULL;
+ gchar *linkname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_pargfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_bname, offset, &bname);
+ offset = glusterfs_rpc_dissect_mode(tree, tvb, hf_glusterfs_umask, offset);
+
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_linkname, offset, &linkname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_symlink_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_rename_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+
+ gchar *oldbname = NULL;
+ gchar *newbname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_oldgfid, offset);
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_newgfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_oldbname, offset, &oldbname);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_newbname, offset, &newbname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_rename_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreOldParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostOldParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreNewParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostNewParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_link_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->preparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postparent */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostParent IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_link_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ gchar *newbname = NULL;
+
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_oldgfid, offset);
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_newgfid, offset);
+ offset = dissect_rpc_string(tvb, tree, hf_glusterfs_newbname, offset, &newbname);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_truncate_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->prestat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postStat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_truncate_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_offset, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_open_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_open_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_read_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->stat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "Stat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_size, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_read_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_offset, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_size, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_write_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->prestat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->poststat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_write_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_offset, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_glusterfs_size, offset);
+ offset = glusterfs_rpc_dissect_flags(tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_statfs_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+ offset = glusterfs_rpc_dissect_statfs(tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_statfs_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_flush_call(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ offset = glusterfs_rpc_dissect_gfid(tree, tvb, hf_glusterfs_gfid, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_glusterfs_fd, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+
+static int
+glusterfs_gfs3_3_op_fsync_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *iatt_item;
+ proto_tree *iatt_tree;
+
+ offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->prestat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PreStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+
+ /* FIXME: describe this better - gf_iatt (xdrs, &objp->postStat */
+ iatt_item = proto_tree_add_text(tree, tvb, offset, -1, "PostStat IATT");
+ iatt_tree = proto_item_add_subtree(iatt_item, ett_glusterfs_iatt);
+ offset = glusterfs_rpc_dissect_gf_iatt(iatt_tree, tvb, offset);
+ offset = gluster_rpc_dissect_dict(tree, tvb, hf_glusterfs_dict, offset);
+
+ return offset;
+}
+static int
+glusterfs_gfs3_3_op_fsync_call(tvbuff_t *tvb, int offset,