-/* XXX TODO:
- Someone should take packet-iscsi.c apart and break all the SCSI-CDB stuff
- out and put SCSI-CDB in packet-scsi.c instead.
- Then packet-iscsi.c only contains the iscsi layer and it will call
- packet-scsi.c to dissect the cdb's.
- Then we can call packet-scsi.c to dissect the scsi cdb's
- from here as well.
-
- volunteers?
-*/
/* packet-ndmp.c
* Routines for NDMP dissection
* 2001 Ronnie Sahlberg (see AUTHORS for email)
*
- * $Id: packet-ndmp.c,v 1.5 2002/01/05 20:08:47 guy Exp $
+ * $Id: packet-ndmp.c,v 1.25 2003/12/27 04:01:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* see www.ndmp.org for protocol specifications.
- this file implements version 3 of ndmp
+ this file implements version 3 of ndmp
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
#include <stdio.h>
#include <string.h>
#include <glib.h>
-#include "packet.h"
+#include <epan/packet.h>
+#include <epan/conversation.h>
#include "packet-rpc.h"
+#include "packet-scsi.h"
+#include "packet-frame.h"
#include "prefs.h"
+#include "reassemble.h"
+#include "rpc_defrag.h"
#define TCP_PORT_NDMP 10000
-#define NDMP_FRAGLEN 0x7fffffffL
-
static int proto_ndmp = -1;
static int hf_ndmp_version = -1;
-static int hf_ndmp_size = -1;
static int hf_ndmp_header = -1;
static int hf_ndmp_sequence = -1;
static int hf_ndmp_reply_sequence = -1;
static int hf_ndmp_scsi_controller = -1;
static int hf_ndmp_scsi_id = -1;
static int hf_ndmp_scsi_lun = -1;
+static int hf_ndmp_execute_cdb_flags_data_in = -1;
+static int hf_ndmp_execute_cdb_flags_data_out = -1;
+static int hf_ndmp_execute_cdb_timeout = -1;
+static int hf_ndmp_execute_cdb_datain_len = -1;
+static int hf_ndmp_execute_cdb_cdb_len = -1;
+static int hf_ndmp_execute_cdb_dataout = -1;
+static int hf_ndmp_execute_cdb_status = -1;
+static int hf_ndmp_execute_cdb_dataout_len = -1;
+static int hf_ndmp_execute_cdb_datain = -1;
+static int hf_ndmp_execute_cdb_sns_len = -1;
static int hf_ndmp_tape_invalid_file_num = -1;
static int hf_ndmp_tape_invalid_soft_errors = -1;
static int hf_ndmp_tape_invalid_block_size = -1;
static gint ett_ndmp_butype_attrs = -1;
static gint ett_ndmp_fs_invalid = -1;
static gint ett_ndmp_tape_attr = -1;
+static gint ett_ndmp_execute_cdb_flags = -1;
+static gint ett_ndmp_execute_cdb_cdb = -1;
+static gint ett_ndmp_execute_cdb_sns = -1;
+static gint ett_ndmp_execute_cdb_payload = -1;
static gint ett_ndmp_tape_invalid = -1;
static gint ett_ndmp_tape_flags = -1;
static gint ett_ndmp_addr = -1;
};
/* desegmentation of NDMP packets */
-static gboolean ndmp_desegment = FALSE;
-
+static gboolean ndmp_desegment = TRUE;
+/* defragmentation of fragmented NDMP records */
+static gboolean ndmp_defragment = FALSE;
#define NDMP_MESSAGE_REQUEST 0x00
#define NDMP_MESSAGE_REPLY 0x01
{0, NULL}
};
-
static int
-dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* version number */
proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, FALSE);
}
static int
-dissect_error(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_error(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_ndmp_get_host_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_ndmp_get_host_info_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
offset += 4;
/* hostname */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_hostname, offset, NULL);
/* os type */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_os_type, offset, NULL);
/* os version */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_os_vers, offset, NULL);
/* hostid */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_hostid, offset, NULL);
return offset;
};
static int
-dissect_ndmp_addr_type(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_ndmp_addr_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
- /*address type*/
proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, FALSE);
offset += 4;
}
static int
-dissect_ndmp_config_get_connection_type_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_ndmp_addr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
+{
+ /*address type*/
+ return dissect_ndmp_addr_type(tvb, offset, pinfo, tree);
+}
+
+static int
+dissect_ndmp_config_get_connection_type_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
{0,NULL}
};
static int
-dissect_auth_type(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_auth_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
- /* auth type */
proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, FALSE);
offset += 4;
}
static int
-dissect_auth_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_auth_type_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
+{
+ /* auth type */
+ return dissect_auth_type(tvb, offset, pinfo, tree);
+}
+
+static int
+dissect_auth_attr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
guint type;
-
+
type=tvb_get_ntohl(tvb,offset);
/* auth type */
case NDMP_AUTH_TEXT:
break;
case NDMP_AUTH_MD5:
- proto_tree_add_item(tree, hf_ndmp_auth_challenge,
+ proto_tree_add_item(tree, hf_ndmp_auth_challenge,
tvb, offset, 64, FALSE);
offset+=64;
}
}
static int
-dissect_default_env(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_default_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
/* name */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_butype_env_name, offset, NULL);
/* value */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_butype_env_value, offset, NULL);
return offset;
"Normal recover. Do NOT use utf8"
};
static int
-dissect_butype_attrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_butype_attrs(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Attributes: 0x%08x ", flags);
+ "Attributes: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_butype_attrs);
}
dissect_butype_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
/*butype name*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_butype_name, offset, NULL);
/* default env */
}
static int
-dissect_get_butype_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_butype_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
"Used inode count is VALID"
};
static int
-dissect_fs_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_fs_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Invalids: 0x%08x ", flags);
+ "Invalids: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_fs_invalid);
}
}
static int
-dissect_fs_env(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_fs_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
/* name */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_env_name, offset, NULL);
/* value */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_env_value, offset, NULL);
return offset;
offset=dissect_fs_invalid(tvb, offset, pinfo, tree);
/* fs type */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_fs_type, offset, NULL);
/* fs logical device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_logical_device, offset, NULL);
/* fs physical device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_physical_device, offset, NULL);
/*total_size*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_total_size,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_size,
offset);
/*used_size*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_used_size,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_size,
offset);
/*avail_size*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_avail_size,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_avail_size,
offset);
/*total_inodes*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_total_inodes,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_inodes,
offset);
/*used_inodes*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_used_inodes,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_inodes,
offset);
/* env */
dissect_fs_env, hf_ndmp_fs_env);
/* status */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_fs_status, offset, NULL);
return offset;
}
static int
-dissect_get_fs_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_fs_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
"Device does NOT support unload"
};
static int
-dissect_tape_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_tape_attr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Attributes: 0x%08x ", flags);
+ "Attributes: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_tape_attr);
}
}
static int
-dissect_tape_capability(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_capability(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
/* name */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_tape_capability_name, offset, NULL);
/* value */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_tape_capability_value, offset, NULL);
return offset;
dissect_tape_dev_cap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
/* device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_tape_device, offset, NULL);
/* tape attributes */
dissect_tape_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
/* model */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_tape_model, offset, NULL);
/* device capabilites */
}
static int
-dissect_get_tape_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_tape_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
dissect_scsi_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
/* model */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_scsi_model, offset, NULL);
/* device capabilites */
}
static int
-dissect_get_scsi_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_scsi_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_get_server_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_get_server_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
offset += 4;
/* vendor */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_server_vendor, offset, NULL);
/* product */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_server_product, offset, NULL);
/* revision */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_server_revision, offset, NULL);
}
static int
-dissect_scsi_device(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_scsi_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_scsi_device, offset, NULL);
return offset;
}
static int
-dissect_scsi_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_scsi_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_scsi_set_state_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_scsi_set_state_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_scsi_device, offset, NULL);
/* controller */
return offset;
}
+static int
+dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
+{
+ proto_item* item = NULL;
+ proto_tree* tree = NULL;
+ guint32 flags;
+
+ flags = tvb_get_ntohl(tvb, offset);
+ if (parent_tree) {
+ item = proto_tree_add_text(parent_tree, tvb, offset, 4,
+ "Flags: 0x%08x", flags);
+ tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_flags);
+ }
+
+ proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_in,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_out,
+ tvb, offset, 4, flags);
+ offset += 4;
+ return offset;
+}
+
+static int
+dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *parent_tree, gint devtype)
+{
+ proto_item* item = NULL;
+ proto_tree* tree = NULL;
+ guint32 cdb_len;
+ guint32 cdb_len_full;
+
+ cdb_len = tvb_get_ntohl(tvb, offset);
+ cdb_len_full = rpc_roundup(cdb_len);
+
+ if (parent_tree) {
+ item = proto_tree_add_text(parent_tree, tvb, offset,
+ 4+cdb_len_full, "CDB");
+ tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_cdb);
+ }
+
+ proto_tree_add_uint(tree, hf_ndmp_execute_cdb_cdb_len, tvb, offset, 4,
+ cdb_len);
+ offset += 4;
+
+ if (cdb_len != 0) {
+ dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len, devtype);
+ offset += cdb_len_full;
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree,
+ char *name, int hf_len, gboolean isreq)
+{
+ proto_item* item = NULL;
+ proto_tree* tree = NULL;
+ guint32 payload_len;
+ guint32 payload_len_full;
+
+ payload_len = tvb_get_ntohl(tvb, offset);
+ payload_len_full = rpc_roundup(payload_len);
+
+ if (parent_tree) {
+ item = proto_tree_add_text(parent_tree, tvb, offset,
+ 4+payload_len_full, "%s", name);
+ tree = proto_item_add_subtree(item,
+ ett_ndmp_execute_cdb_payload);
+ }
+
+ proto_tree_add_uint(tree, hf_len, tvb, offset, 4, payload_len);
+ offset += 4;
+
+ if (payload_len != 0) {
+ dissect_scsi_payload(tvb, pinfo, tree, offset, isreq,
+ payload_len);
+ offset += payload_len_full;
+ }
+
+ return offset;
+}
+
+/*
+ * XXX - we assume that NDMP_SCSI_EXECUTE_CDB requests only go to SCSI Media
+ * Changer devices and NDMP_TAPE_EXECUTE_CDB only go to SCSI Sequential
+ * Access devices.
+ *
+ * If that's not the case, we'll have to use the SCSI dissector's mechanisms
+ * for saving inquiry data for devices, and use inquiry data when available.
+ * Unfortunately, that means we need to save the name of the device, and
+ * use it as a device identifier; as the name isn't available in the
+ * NDMP_SCSI_EXECUTE_CDB or NDMP_TAPE_EXECUTE_CDB messages, that means
+ * we need to remember the currently-opened "SCSI" and "TAPE" devices
+ * from NDMP_SCSI_OPEN and NDMP_TAPE_OPEN, and attach to all frames
+ * that are the ones that trigger the dissection of NDMP_SCSI_EXECUTE_CDB
+ * or NDMP_TAPE_EXECUTE_CDB requests pointers to those names.
+ */
+static int
+dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq, gint devtype)
+{
+ conversation_t *conversation;
+ scsi_task_id_t task_key;
+
+ /*
+ * We need to provide SCSI task information to the SCSI
+ * dissection routines. We use a conversation plus the
+ * sequence number in requests and the reply sequence
+ * number in replies to identify SCSI tasks.
+ */
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+ if (conversation == NULL) {
+ conversation = conversation_new(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+ }
+ task_key.conv_id = conversation->index;
+ task_key.task_id = seq;
+ pinfo->private_data = &task_key;
+
+ /* flags */
+ offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
+
+ /* timeout */
+ proto_tree_add_item(tree, hf_ndmp_execute_cdb_timeout, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* datain_len */
+ proto_tree_add_item(tree, hf_ndmp_execute_cdb_datain_len, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* CDB */
+ offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree, devtype);
+
+ /* dataout */
+ offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
+ "Data out", hf_ndmp_execute_cdb_dataout_len, TRUE);
+
+ return offset;
+}
+
+static int
+dissect_execute_cdb_request_mc(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq)
+{
+ return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
+ SCSI_DEV_SMC);
+}
+
+static int
+dissect_execute_cdb_request_tape(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq)
+{
+ return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
+ SCSI_DEV_SSC);
+}
+
+static int
+dissect_execute_cdb_sns(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+{
+ proto_item* item = NULL;
+ proto_tree* tree = NULL;
+ guint32 sns_len;
+ guint32 sns_len_full;
+
+ sns_len = tvb_get_ntohl(tvb, offset);
+ sns_len_full = rpc_roundup(sns_len);
+
+ if (parent_tree) {
+ item = proto_tree_add_text(parent_tree, tvb, offset,
+ 4+sns_len_full, "Sense data");
+ tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_sns);
+ }
+
+ proto_tree_add_uint(tree, hf_ndmp_execute_cdb_sns_len, tvb, offset, 4,
+ sns_len);
+ offset += 4;
+
+ if (sns_len != 0) {
+ dissect_scsi_snsinfo(tvb, pinfo, tree, offset, sns_len);
+ offset += sns_len_full;
+ }
+
+ return offset;
+}
+
+static int
+dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq)
+{
+ conversation_t *conversation;
+ scsi_task_id_t task_key;
+
+ /*
+ * We need to provide SCSI task information to the SCSI
+ * dissection routines. We use a conversation plus the
+ * sequence number in requests and the reply sequence
+ * number in replies to identify SCSI tasks.
+ */
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+ if (conversation != NULL) {
+ task_key.conv_id = conversation->index;
+ task_key.task_id = seq;
+ pinfo->private_data = &task_key;
+ } else {
+ /* no conversation, meaning we didn't see the request */
+ pinfo->private_data = NULL;
+ }
+
+ /* error */
+ proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* status */
+ proto_tree_add_item(tree, hf_ndmp_execute_cdb_status, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* dataout_len */
+ proto_tree_add_item(tree, hf_ndmp_execute_cdb_dataout_len, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* datain */
+ offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
+ "Data in", hf_ndmp_execute_cdb_datain_len, FALSE);
+
+ /* ext_sense */
+ offset = dissect_execute_cdb_sns(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
#define NDMP_TAPE_OPEN_MODE_READ 0
#define NDMP_TAPE_OPEN_MODE_RDWR 1
static const value_string tape_open_mode_vals[] = {
};
static int
-dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* device */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_tape_device, offset, NULL);
/* open mode */
"Partition is valid"
};
static int
-dissect_tape_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_tape_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Invalids: 0x%08x ", flags);
+ "Invalids: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_tape_invalid);
}
"This device does NOT support unload"
};
static int
-dissect_tape_flags(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_tape_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Flags: 0x%08x ", flags);
+ "Flags: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_tape_flags);
}
}
static int
-dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* invalid bits */
offset=dissect_tape_invalid(tvb, offset, pinfo, tree);
offset += 4;
/* total_space */
- offset = dissect_rpc_uint64(tvb, pinfo, tree,hf_ndmp_tape_total_space,
+ offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_total_space,
offset);
/* space_remain */
- offset = dissect_rpc_uint64(tvb, pinfo, tree,hf_ndmp_tape_space_remain,
+ offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_space_remain,
offset);
/* partition */
};
static int
-dissect_tape_mtio_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_mtio_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* op */
proto_tree_add_item(tree, hf_ndmp_tape_mtio_op, tvb, offset, 4, FALSE);
}
static int
-dissect_tape_mtio_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_mtio_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
};
static int
-dissect_ndmp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_ndmp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
/* IP addr */
proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, FALSE);
offset+=4;
-
+
/* TCP port */
proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, FALSE);
offset+=4;
-
+
break;
case NDMP_ADDR_FC:
/* FCAL loop id */
break;
case NDMP_ADDR_IPC:
/* IPC address */
- offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_addr_ipc, offset);
+ offset = dissect_rpc_data(tvb, tree, hf_ndmp_addr_ipc, offset);
break;
}
return offset;
}
-
+
static int
-dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
};
static int
-dissect_mover_listen_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_listen_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* mode */
proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, FALSE);
}
static int
-dissect_mover_listen_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_listen_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_mover_set_window_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_set_window_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* window offset */
proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, FALSE);
}
static int
-dissect_mover_set_record_size_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_set_record_size_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* record size */
proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, FALSE);
}
static int
-dissect_mover_connect_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_mover_connect_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* mode */
proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, FALSE);
}
static int
-dissect_log_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_log_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* file */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_file_name, offset, NULL);
/* error */
};
static int
-dissect_log_message_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_log_message_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* type */
proto_tree_add_item(tree, hf_ndmp_log_type, tvb, offset, 4, FALSE);
offset += 4;
/* message */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_log_message, offset, NULL);
return offset;
}
static int
-dissect_notify_data_halted_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_notify_data_halted_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* halt */
proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, FALSE);
offset += 4;
/* reason */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_halt_reason, offset, NULL);
return offset;
};
static int
-dissect_notify_connected_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_notify_connected_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* connected */
proto_tree_add_item(tree, hf_ndmp_connected, tvb, offset, 4, FALSE);
offset += 4;
/* reason */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_connected_reason, offset, NULL);
return offset;
static int
-dissect_notify_mover_paused_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_notify_mover_paused_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
{
/* mover pause */
proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, FALSE);
}
static int
-dissect_auth_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_auth_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
guint type;
-
+
type=tvb_get_ntohl(tvb,offset);
/* auth type */
break;
case NDMP_AUTH_TEXT:
/* auth id */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_auth_id, offset, NULL);
/* auth password */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_auth_password, offset, NULL);
-
+
break;
case NDMP_AUTH_MD5:
/* auth id */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_auth_id, offset, NULL);
/* digest */
- proto_tree_add_item(tree, hf_ndmp_auth_digest,
+ proto_tree_add_item(tree, hf_ndmp_auth_digest,
tvb, offset, 16, FALSE);
offset+=16;
}
return offset;
}
+static int
+dissect_connect_client_auth_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint32 seq _U_)
+{
+ return dissect_auth_data(tvb, offset, pinfo, tree);
+}
static int
-dissect_connect_server_auth_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_connect_server_auth_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_tape_write_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_write_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* data */
- offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_data, offset);
+ offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
return offset;
}
static int
-dissect_tape_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
}
static int
-dissect_tape_read_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_read_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* count */
proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, FALSE);
}
static int
-dissect_tape_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_tape_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
offset += 4;
/* data */
- offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_data, offset);
+ offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
return offset;
}
char *name;
if (parent_tree) {
- item = proto_tree_add_text(parent_tree, tvb, offset, 0,
- "File ");
+ item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+ "File");
tree = proto_item_add_subtree(item, ett_ndmp_file_name);
}
switch(type){
case NDMP_FS_UNIX:
/* file */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_file_name, offset, &name);
if (check_col(pinfo->cinfo, COL_INFO)){
- col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
}
break;
case NDMP_FS_NT:
/* nt file */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_nt_file_name, offset, &name);
if (check_col(pinfo->cinfo, COL_INFO)){
- col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
}
/* dos file */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_dos_file_name, offset, NULL);
break;
default:
/* file */
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_file_name, offset, &name);
if (check_col(pinfo->cinfo, COL_INFO)){
- col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
}
}
if (check_col(pinfo->cinfo, COL_INFO)){
- col_append_fstr(pinfo->cinfo, COL_INFO, "(%s)",
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
val_to_str(type, file_fs_type_vals, "Unknown type") );
}
- proto_item_set_len(item, offset-old_offset);
+ proto_item_set_len(item, offset-old_offset);
return offset;
}
"Group is valid"
};
static int
-dissect_file_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_file_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Invalids: 0x%08x ", flags);
+ "Invalids: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_file_invalids);
}
nstime_t ns;
if (parent_tree) {
- item = proto_tree_add_text(parent_tree, tvb, offset, 0,
+ item = proto_tree_add_text(parent_tree, tvb, offset, -1,
"Stats:");
tree = proto_item_add_subtree(item, ett_ndmp_file_stats);
}
offset += 4;
/*file size*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_file_size,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_file_size,
offset);
/* links */
proto_tree_add_item(tree, hf_ndmp_file_links, tvb, offset, 4, FALSE);
offset += 4;
- proto_item_set_len(item, offset-old_offset);
+ proto_item_set_len(item, offset-old_offset);
return offset;
}
int old_offset=offset;
if (parent_tree) {
- item = proto_tree_add_text(parent_tree, tvb, offset, 0,
+ item = proto_tree_add_text(parent_tree, tvb, offset, -1,
"File:");
tree = proto_item_add_subtree(item, ett_ndmp_file);
}
proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, FALSE);
offset += 8;
- proto_item_set_len(item, offset-old_offset);
+ proto_item_set_len(item, offset-old_offset);
return offset;
}
static int
-dissect_fh_add_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_fh_add_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* files */
offset = dissect_rpc_array(tvb, pinfo, tree, offset,
}
static int
-dissect_fh_add_dir_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_fh_add_dir_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* dirs */
offset = dissect_rpc_array(tvb, pinfo, tree, offset,
static int
-dissect_fh_add_node_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_fh_add_node_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* node */
offset = dissect_rpc_array(tvb, pinfo, tree, offset,
}
static int
-dissect_data_start_backup_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_data_start_backup_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/*butype name*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_butype_name, offset, NULL);
/* default env */
}
static int
-dissect_nlist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_nlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree)
{
/*original path*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_bu_original_path, offset, NULL);
/*destination dir*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_bu_destination_dir, offset, NULL);
/*new name*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_bu_new_name, offset, NULL);
/*other name*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_bu_other_name, offset, NULL);
/* node */
static int
-dissect_data_start_recover_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_data_start_recover_request(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint32 seq _U_)
{
/* default env */
offset = dissect_rpc_array(tvb, pinfo, tree, offset,
dissect_nlist, hf_ndmp_nlist);
/*butype name*/
- offset = dissect_rpc_string(tvb, pinfo, tree,
+ offset = dissect_rpc_string(tvb, tree,
hf_ndmp_butype_name, offset, NULL);
return offset;
}
static int
-dissect_data_get_env_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_data_get_env_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
/* error */
proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
"Estimated Time Remaining is valid"
};
static int
-dissect_state_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+dissect_state_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *parent_tree)
{
proto_item* item = NULL;
proto_tree* tree = NULL;
flags=tvb_get_ntohl(tvb, offset);
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, 4,
- "Invalids: 0x%08x ", flags);
+ "Invalids: 0x%08x", flags);
tree = proto_item_add_subtree(item, ett_ndmp_state_invalids);
}
};
static int
-dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq _U_)
{
nstime_t ns;
offset += 4;
/*bytes processed*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_data_bytes_processed,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_bytes_processed,
offset);
/*est bytes remain*/
- offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_data_est_bytes_remain,
+ offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_est_bytes_remain,
offset);
/* est time remain */
typedef struct _ndmp_command {
guint32 cmd;
- int (*request) (tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
- int (*response)(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+ int (*request) (tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq);
+ int (*response)(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 seq);
} ndmp_command;
static const ndmp_command ndmp_commands[] = {
- {NDMP_CONFIG_GET_HOST_INFO,
+ {NDMP_CONFIG_GET_HOST_INFO,
NULL, dissect_ndmp_get_host_info_reply},
- {NDMP_CONFIG_GET_CONNECTION_TYPE,
+ {NDMP_CONFIG_GET_CONNECTION_TYPE,
NULL, dissect_ndmp_config_get_connection_type_reply},
- {NDMP_CONFIG_GET_AUTH_ATTR,
- dissect_auth_type, dissect_auth_attr},
- {NDMP_CONFIG_GET_BUTYPE_INFO,
+ {NDMP_CONFIG_GET_AUTH_ATTR,
+ dissect_get_auth_type_request, dissect_auth_attr_msg},
+ {NDMP_CONFIG_GET_BUTYPE_INFO,
NULL, dissect_get_butype_info_reply},
- {NDMP_CONFIG_GET_FS_INFO,
+ {NDMP_CONFIG_GET_FS_INFO,
NULL, dissect_get_fs_info_reply},
- {NDMP_CONFIG_GET_TAPE_INFO,
+ {NDMP_CONFIG_GET_TAPE_INFO,
NULL, dissect_get_tape_info_reply},
- {NDMP_CONFIG_GET_SCSI_INFO,
+ {NDMP_CONFIG_GET_SCSI_INFO,
NULL, dissect_get_scsi_info_reply},
- {NDMP_CONFIG_GET_SERVER_INFO,
+ {NDMP_CONFIG_GET_SERVER_INFO,
NULL, dissect_get_server_info_reply},
- {NDMP_SCSI_OPEN,
- dissect_scsi_device, dissect_error},
- {NDMP_SCSI_CLOSE,
+ {NDMP_SCSI_OPEN,
+ dissect_scsi_open_request, dissect_error},
+ {NDMP_SCSI_CLOSE,
NULL, dissect_error},
- {NDMP_SCSI_GET_STATE,
+ {NDMP_SCSI_GET_STATE,
NULL, dissect_scsi_get_state_reply},
- {NDMP_SCSI_SET_TARGET,
+ {NDMP_SCSI_SET_TARGET,
dissect_scsi_set_state_request, dissect_error},
- {NDMP_SCSI_RESET_DEVICE,
+ {NDMP_SCSI_RESET_DEVICE,
NULL, dissect_error},
- {NDMP_SCSI_RESET_BUS,
+ {NDMP_SCSI_RESET_BUS,
NULL, dissect_error},
- {NDMP_SCSI_EXECUTE_CDB, NULL,NULL},
- {NDMP_TAPE_OPEN,
+ {NDMP_SCSI_EXECUTE_CDB,
+ dissect_execute_cdb_request_mc, dissect_execute_cdb_reply},
+ {NDMP_TAPE_OPEN,
dissect_tape_open_request, dissect_error},
- {NDMP_TAPE_CLOSE,
+ {NDMP_TAPE_CLOSE,
NULL, dissect_error},
- {NDMP_TAPE_GET_STATE,
+ {NDMP_TAPE_GET_STATE,
NULL, dissect_tape_get_state_reply},
- {NDMP_TAPE_MTIO,
+ {NDMP_TAPE_MTIO,
dissect_tape_mtio_request, dissect_tape_mtio_reply},
- {NDMP_TAPE_WRITE,
+ {NDMP_TAPE_WRITE,
dissect_tape_write_request, dissect_tape_write_reply},
- {NDMP_TAPE_READ,
+ {NDMP_TAPE_READ,
dissect_tape_read_request, dissect_tape_read_reply},
- {NDMP_TAPE_EXECUTE_CDB, NULL,NULL},
- {NDMP_DATA_GET_STATE,
+ {NDMP_TAPE_EXECUTE_CDB,
+ dissect_execute_cdb_request_tape, dissect_execute_cdb_reply},
+ {NDMP_DATA_GET_STATE,
NULL, dissect_data_get_state_reply},
{NDMP_DATA_START_BACKUP,
dissect_data_start_backup_request, dissect_error },
dissect_data_start_recover_request, dissect_error },
{NDMP_DATA_ABORT,
NULL, dissect_error},
- {NDMP_DATA_GET_ENV,
+ {NDMP_DATA_GET_ENV,
NULL, dissect_data_get_env_reply},
- {NDMP_DATA_STOP,
+ {NDMP_DATA_STOP,
NULL, dissect_error},
- {NDMP_DATA_LISTEN,
- dissect_ndmp_addr_type, dissect_mover_listen_reply},
- {NDMP_DATA_CONNECT,
- dissect_ndmp_addr, dissect_error},
- {NDMP_NOTIFY_DATA_HALTED,
+ {NDMP_DATA_LISTEN,
+ dissect_ndmp_addr_msg, dissect_mover_listen_reply},
+ {NDMP_DATA_CONNECT,
+ dissect_ndmp_addr_msg, dissect_error},
+ {NDMP_NOTIFY_DATA_HALTED,
dissect_notify_data_halted_request, NULL},
- {NDMP_NOTIFY_CONNECTED,
+ {NDMP_NOTIFY_CONNECTED,
dissect_notify_connected_request, NULL},
- {NDMP_NOTIFY_MOVER_HALTED,
+ {NDMP_NOTIFY_MOVER_HALTED,
dissect_notify_data_halted_request, NULL},
- {NDMP_NOTIFY_MOVER_PAUSED,
+ {NDMP_NOTIFY_MOVER_PAUSED,
dissect_notify_mover_paused_request, NULL},
- {NDMP_NOTIFY_DATA_READ,
+ {NDMP_NOTIFY_DATA_READ,
dissect_mover_set_window_request, NULL},
- {NDMP_LOG_FILE,
+ {NDMP_LOG_FILE,
dissect_log_file_request, NULL},
- {NDMP_LOG_MESSAGE,
+ {NDMP_LOG_MESSAGE,
dissect_log_message_request, NULL},
- {NDMP_FH_ADD_FILE,
+ {NDMP_FH_ADD_FILE,
dissect_fh_add_file_request, NULL},
- {NDMP_FH_ADD_DIR,
+ {NDMP_FH_ADD_DIR,
dissect_fh_add_dir_request, NULL},
- {NDMP_FH_ADD_NODE,
+ {NDMP_FH_ADD_NODE,
dissect_fh_add_node_request, NULL},
- {NDMP_CONNECT_OPEN,
+ {NDMP_CONNECT_OPEN,
dissect_connect_open_request, dissect_error},
- {NDMP_CONNECT_CLIENT_AUTH,
- dissect_auth_data, dissect_error},
- {NDMP_CONNECT_CLOSE,
+ {NDMP_CONNECT_CLIENT_AUTH,
+ dissect_connect_client_auth_request, dissect_error},
+ {NDMP_CONNECT_CLOSE,
NULL,NULL},
- {NDMP_CONNECT_SERVER_AUTH,
- dissect_auth_attr, dissect_connect_server_auth_reply},
- {NDMP_MOVER_GET_STATE,
+ {NDMP_CONNECT_SERVER_AUTH,
+ dissect_auth_attr_msg, dissect_connect_server_auth_reply},
+ {NDMP_MOVER_GET_STATE,
NULL, dissect_mover_get_state_reply},
- {NDMP_MOVER_LISTEN,
+ {NDMP_MOVER_LISTEN,
dissect_mover_listen_request, dissect_mover_listen_reply},
- {NDMP_MOVER_CONTINUE,
+ {NDMP_MOVER_CONTINUE,
NULL, dissect_error},
- {NDMP_MOVER_ABORT,
+ {NDMP_MOVER_ABORT,
NULL, dissect_error},
- {NDMP_MOVER_STOP,
+ {NDMP_MOVER_STOP,
NULL, dissect_error},
- {NDMP_MOVER_SET_WINDOW,
+ {NDMP_MOVER_SET_WINDOW,
dissect_mover_set_window_request, dissect_error},
- {NDMP_MOVER_READ,
+ {NDMP_MOVER_READ,
dissect_mover_set_window_request, dissect_error},
- {NDMP_MOVER_CLOSE,
+ {NDMP_MOVER_CLOSE,
NULL, dissect_error},
- {NDMP_MOVER_SET_RECORD_SIZE,
+ {NDMP_MOVER_SET_RECORD_SIZE,
dissect_mover_set_record_size_request, dissect_error},
- {NDMP_MOVER_CONNECT,
+ {NDMP_MOVER_CONNECT,
dissect_mover_connect_request, dissect_error},
{0, NULL,NULL}
};
offset += 4;
if (check_col(pinfo->cinfo, COL_INFO)){
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s ",
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
val_to_str(nh->msg, msg_vals, "Unknown Message (0x%02x)"),
val_to_str(nh->type, msg_type_vals, "Unknown Type (0x%02x)")
);
int i;
proto_item *cmd_item=NULL;
proto_tree *cmd_tree=NULL;
- guint32 size;
-
- /* the size of the current PDU */
- size = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(tree, hf_ndmp_size, tvb, offset, 4, size&NDMP_FRAGLEN);
- offset += 4;
offset=dissect_ndmp_header(tvb, offset, pinfo, tree, nh);
if(ndmp_commands[i].cmd==0){
/* we do not know this message */
- proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Unknown type of NDMP message: 0x%02x", nh->msg);
+ proto_tree_add_text(tree, tvb, offset, -1, "Unknown type of NDMP message: 0x%02x", nh->msg);
offset+=tvb_length_remaining(tvb, offset);
return offset;
}
- if(tree){
- cmd_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
- msg_vals[i].strptr);
- cmd_tree = proto_item_add_subtree(cmd_item, ett_ndmp);
+ if (tvb_reported_length_remaining(tvb, offset) > 0) {
+ if(tree){
+ cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
+ msg_vals[i].strptr);
+ cmd_tree = proto_item_add_subtree(cmd_item, ett_ndmp);
+ }
}
if(nh->type==NDMP_MESSAGE_REQUEST){
if(ndmp_commands[i].request){
- offset=ndmp_commands[i].request(tvb, offset, pinfo, cmd_tree);
+ offset=ndmp_commands[i].request(tvb, offset, pinfo, cmd_tree,
+ nh->seq);
}
} else {
if(ndmp_commands[i].response){
- offset=ndmp_commands[i].response(tvb, offset, pinfo, cmd_tree);
+ offset=ndmp_commands[i].response(tvb, offset, pinfo, cmd_tree,
+ nh->rep_seq);
}
}
return offset;
}
-static void
-dissect_ndmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+static gboolean
+dissect_ndmp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
+ guint32 rpc_rm, gboolean first_pdu)
{
- int offset = 0;
- guint32 size, available_bytes;
+ int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
+ guint32 size;
struct ndmp_header nh;
- proto_item *item=NULL;
- proto_tree *tree=NULL;
-
-
- if(parent_tree){
- item = proto_tree_add_item(parent_tree, proto_ndmp, tvb, offset, 0, FALSE);
- tree = proto_item_add_subtree(item, ett_ndmp);
+ proto_item *ndmp_item = NULL;
+ proto_tree *ndmp_tree = NULL;
+
+ /* size of this NDMP PDU */
+ size = tvb_length_remaining(tvb, offset);
+ if (size < 24) {
+ /* too short to be NDMP */
+ return FALSE;
}
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_add_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
-
+ /*
+ * Check the NDMP header, if we have it.
+ */
+ nh.seq = tvb_get_ntohl(tvb, offset);
+ nh.time = tvb_get_ntohl(tvb, offset+4);
+ nh.type = tvb_get_ntohl(tvb, offset+8);
+ nh.msg = tvb_get_ntohl(tvb, offset+12);
+ nh.rep_seq = tvb_get_ntohl(tvb, offset+16);
+ nh.err = tvb_get_ntohl(tvb, offset+20);
+
+ if (nh.type > 1)
+ return FALSE;
+ if (nh.msg > 0xa09 || nh.msg == 0)
+ return FALSE;
+ if (nh.err > 0x17)
+ return FALSE;
+
+ /*
+ * Check if this is the last fragment.
+ */
+ if (!(rpc_rm & RPC_RM_LASTFRAG)) {
+ /*
+ * This isn't the last fragment.
+ * If we're doing reassembly, just return
+ * TRUE to indicate that this looks like
+ * the beginning of an NDMP message,
+ * and let them do reassembly.
+ */
+ if (ndmp_defragment)
+ return TRUE;
+ }
- /* loop through the packet, dissecting multiple NDMP pdus*/
- do {
- available_bytes = tvb_length_remaining(tvb, offset);
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if (first_pdu)
+ col_clear(pinfo->cinfo, COL_INFO);
+ else
+ col_append_fstr(pinfo->cinfo, COL_INFO, "; ");
+ }
- /* size of this NDMP PDU */
- size = (tvb_get_ntohl(tvb, offset)&NDMP_FRAGLEN) + 4;
- if(size<28){
- /* too short to be NDMP */
- return;
- }
+ if (tree) {
+ ndmp_item = proto_tree_add_item(tree, proto_ndmp,
+ tvb, 0, -1, FALSE);
+ ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
- /* check the ndmp header, if we have it */
- if(available_bytes>=28){
- nh.seq=tvb_get_ntohl(tvb, offset+4);
- nh.time=tvb_get_ntohl(tvb, offset+8);
- nh.type=tvb_get_ntohl(tvb, offset+12);
- nh.msg=tvb_get_ntohl(tvb, offset+16);
- nh.rep_seq=tvb_get_ntohl(tvb, offset+20);
- nh.err=tvb_get_ntohl(tvb, offset+24);
-
- if(nh.type>1){
- return;
- }
- if((nh.msg>0xa09)||(nh.msg==0)){
- return;
- }
- if(nh.err>0x17){
- return;
- }
+ if (is_tcp) {
+ show_rpc_fraginfo(tvb, frag_tvb, ndmp_tree, rpc_rm,
+ ipfd_head, pinfo);
}
+ }
- /* desegmentation */
- if(ndmp_desegment){
- if(pinfo->can_desegment
- && size>available_bytes) {
- pinfo->desegment_offset = offset;
- pinfo->desegment_len = size-available_bytes;
- return;
- }
- }
+ /*
+ * We cannot trust what dissect_ndmp_cmd() tells us, as there
+ * are implementations which pad some additional data after
+ * the PDU. We MUST use size.
+ */
+ dissect_ndmp_cmd(tvb, offset, pinfo, ndmp_tree, &nh);
+ return TRUE;
+}
- if(available_bytes<28){
- /* too short to be a NDMP packet */
+static void
+dissect_ndmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int offset = 0;
+ int len;
+ gboolean first_pdu = TRUE;
+
+ while (tvb_reported_length_remaining(tvb, offset) != 0) {
+ /*
+ * Process this fragment.
+ */
+ len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
+ dissect_ndmp_message, FALSE, proto_ndmp, ett_ndmp,
+ ndmp_defragment, first_pdu);
+ first_pdu = FALSE;
+ if (len < 0) {
+ /*
+ * We need more data from the TCP stream for
+ * this fragment.
+ */
return;
}
+ if (len == 0) {
+ /*
+ * It's not NDMP. Stop processing.
+ */
+ break;
+ }
- /* We can not trust what dissect_ndmp_cmd() tells us since
- there are implementations which pads some additional data
- after the PDU. We MUST use size.
- */
- dissect_ndmp_cmd(tvb, offset, pinfo, tree, &nh);
- offset += size;
- } while(offset<(int)tvb_reported_length(tvb));
-
- proto_item_set_len(item, offset);
+ offset += len;
+ }
}
-
-
-
void
proto_register_ndmp(void)
{
static hf_register_info hf_ndmp[] = {
- { &hf_ndmp_size, {
- "Size", "ndmp.size", FT_UINT32, BASE_DEC,
- NULL, 0, "Size of this NDMP PDU", HFILL }},
-
{ &hf_ndmp_header, {
"NDMP Header", "ndmp.header", FT_NONE, 0,
NULL, 0, "NDMP Header", HFILL }},
"LUN", "ndmp.scsi.lun", FT_UINT32, BASE_DEC,
NULL, 0, "Target LUN", HFILL }},
+ { &hf_ndmp_execute_cdb_flags_data_in, {
+ "DATA_IN", "ndmp.execute_cdb.flags.data_in", FT_BOOLEAN, 32,
+ NULL, 0x00000001, "DATA_IN", HFILL }},
+
+ { &hf_ndmp_execute_cdb_flags_data_out, {
+ "DATA_OUT", "ndmp.execute_cdb.flags.data_out", FT_BOOLEAN, 32,
+ NULL, 0x00000002, "DATA_OUT", HFILL }},
+
+ { &hf_ndmp_execute_cdb_timeout, {
+ "Timeout", "ndmp.execute_cdb.timeout", FT_UINT32, BASE_DEC,
+ NULL, 0, "Reselect timeout, in milliseconds", HFILL }},
+
+ { &hf_ndmp_execute_cdb_datain_len, {
+ "Data in length", "ndmp.execute_cdb.datain_len", FT_UINT32, BASE_DEC,
+ NULL, 0, "Expected length of data bytes to read", HFILL }},
+
+ { &hf_ndmp_execute_cdb_cdb_len, {
+ "CDB length", "ndmp.execute_cdb.cdb_len", FT_UINT32, BASE_DEC,
+ NULL, 0, "Length of CDB", HFILL }},
+
+ { &hf_ndmp_execute_cdb_dataout, {
+ "Data out", "ndmp.execute_cdb.dataout", FT_BYTES, BASE_NONE,
+ NULL, 0, "Data to be transferred to the SCSI device", HFILL }},
+
+ { &hf_ndmp_execute_cdb_status, {
+ "Status", "ndmp.execute_cdb.status", FT_UINT8, BASE_DEC,
+ VALS(scsi_status_val), 0, "SCSI status", HFILL }},
+
+ { &hf_ndmp_execute_cdb_dataout_len, {
+ "Data out length", "ndmp.execute_cdb.dataout_len", FT_UINT32, BASE_DEC,
+ NULL, 0, "Number of bytes transferred to the device", HFILL }},
+
+ { &hf_ndmp_execute_cdb_datain, {
+ "Data in", "ndmp.execute_cdb.datain", FT_BYTES, BASE_NONE,
+ NULL, 0, "Data transferred from the SCSI device", HFILL }},
+
+ { &hf_ndmp_execute_cdb_sns_len, {
+ "Sense data length", "ndmp.execute_cdb.sns_len", FT_UINT32, BASE_DEC,
+ NULL, 0, "Length of sense data", HFILL }},
+
{ &hf_ndmp_tape_open_mode, {
"Mode", "ndmp.tape.open_mode", FT_UINT32, BASE_DEC,
VALS(tape_open_mode_vals), 0, "Mode to open tape in", HFILL }},
{ &hf_ndmp_data_est_time_remain, {
"Est Time Remain", "ndmp.data.est_time_remain", FT_RELATIVE_TIME, BASE_DEC,
NULL, 0, "Estimated time remaining", HFILL }},
-
-
-
};
static gint *ett[] = {
&ett_ndmp_butype_attrs,
&ett_ndmp_fs_invalid,
&ett_ndmp_tape_attr,
+ &ett_ndmp_execute_cdb_flags,
+ &ett_ndmp_execute_cdb_cdb,
+ &ett_ndmp_execute_cdb_sns,
+ &ett_ndmp_execute_cdb_payload,
&ett_ndmp_tape_invalid,
&ett_ndmp_tape_flags,
&ett_ndmp_addr,
&ett_ndmp_file,
&ett_ndmp_file_name,
+ &ett_ndmp_file_stats,
&ett_ndmp_file_invalids,
&ett_ndmp_state_invalids,
};
proto_ndmp = proto_register_protocol("Network Data Management Protocol", "NDMP", "ndmp");
proto_register_field_array(proto_ndmp, hf_ndmp, array_length(hf_ndmp));
-
+
proto_register_subtree_array(ett, array_length(ett));
/* desegmentation */
ndmp_module = prefs_register_protocol(proto_ndmp, NULL);
- prefs_register_bool_preference(ndmp_module, "ndmp.desegment", "Desegment all NDMP messages spanning multiple TCP segments", "Whether the dissector should desegment NDMP over TCP PDUs or not", &ndmp_desegment);
-
+ prefs_register_bool_preference(ndmp_module, "desegment",
+ "Desegment all NDMP messages spanning multiple TCP segments",
+ "Whether the dissector should desegment NDMP messages",
+ &ndmp_desegment);
+ prefs_register_bool_preference(ndmp_module, "defragment",
+ "Defragment all multi-fragment NDMP messages",
+ "Whether the dissector should defragment multi-fragment NDMP messages",
+ &ndmp_defragment);
}
void