* Routines for NDMP dissection
* 2001 Ronnie Sahlberg (see AUTHORS for email)
*
- * $Id: packet-ndmp.c,v 1.15 2002/02/13 01:17:58 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-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;
/* desegmentation of NDMP packets */
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, guint32 seq)
+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,
- guint32 seq)
+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, guint32 seq)
+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)
{
proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, FALSE);
offset += 4;
static int
dissect_ndmp_addr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+ 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)
+ 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)
{
proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, FALSE);
offset += 4;
static int
dissect_get_auth_type_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+ 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,
- proto_tree *tree, guint32 seq)
+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;
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, guint32 seq)
+ 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;
}
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, guint32 seq)
+ 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;
}
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, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+ 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_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+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 */
}
static int
-dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+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;
"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,
}
static int
-dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
+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;
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");
offset += 4;
if (cdb_len != 0) {
- dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len);
+ dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len, devtype);
offset += cdb_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);
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)
+ proto_tree *tree, guint32 seq, gint devtype)
{
conversation_t *conversation;
scsi_task_id_t task_key;
}
task_key.conv_id = conversation->index;
task_key.task_id = seq;
- pinfo->private_data = &task_key;
-
+ pinfo->private_data = &task_key;
+
/* flags */
offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
offset += 4;
/* CDB */
- offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree);
+ offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree, devtype);
/* dataout */
offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
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)
{
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");
/* 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;
};
static int
-dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+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;
"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;
static int
dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+ 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;
}
static int
dissect_connect_client_auth_request(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+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, guint32 seq)
+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;
}
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;
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;
}
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, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+ 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, guint32 seq)
+ 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;
static int
dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 seq)
+ 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 */
} 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,
+ {NDMP_CONFIG_GET_AUTH_ATTR,
dissect_get_auth_type_request, dissect_auth_attr_msg},
- {NDMP_CONFIG_GET_BUTYPE_INFO,
+ {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,
+ {NDMP_SCSI_OPEN,
dissect_scsi_open_request, dissect_error},
- {NDMP_SCSI_CLOSE,
+ {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,
- dissect_execute_cdb_request, dissect_execute_cdb_reply},
- {NDMP_TAPE_OPEN,
+ 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,
- dissect_execute_cdb_request, dissect_execute_cdb_reply},
- {NDMP_DATA_GET_STATE,
+ 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,
+ {NDMP_DATA_LISTEN,
dissect_ndmp_addr_msg, dissect_mover_listen_reply},
- {NDMP_DATA_CONNECT,
+ {NDMP_DATA_CONNECT,
dissect_ndmp_addr_msg, dissect_error},
- {NDMP_NOTIFY_DATA_HALTED,
+ {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,
+ {NDMP_CONNECT_CLIENT_AUTH,
dissect_connect_client_auth_request, dissect_error},
- {NDMP_CONNECT_CLOSE,
+ {NDMP_CONNECT_CLOSE,
NULL,NULL},
- {NDMP_CONNECT_SERVER_AUTH,
+ {NDMP_CONNECT_SERVER_AUTH,
dissect_auth_attr_msg, dissect_connect_server_auth_reply},
- {NDMP_MOVER_GET_STATE,
+ {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);
return offset;
}
- 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 (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){
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)
{
- volatile gboolean first = TRUE;
- volatile 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 *volatile tree=NULL;
- const char *saved_proto;
-
- /* loop through the packet, dissecting multiple NDMP pdus*/
- do {
- available_bytes = tvb_length_remaining(tvb, offset);
-
- /* size of this NDMP PDU */
- size = (tvb_get_ntohl(tvb, offset)&NDMP_FRAGLEN) + 4;
- if(size<28){
- /* too short to be NDMP */
- return;
- }
+ 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;
+ }
- /* desegmentation */
- if(ndmp_desegment){
- if(pinfo->can_desegment
- && size>available_bytes) {
- pinfo->desegment_offset = offset;
- pinfo->desegment_len = size-available_bytes;
- return;
- }
- }
+ /*
+ * 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 the ndmp header, if we have it */
- if(available_bytes<28){
- /* We don't have enough data */
- return;
- }
- 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;
- }
+ /*
+ * 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;
+ }
- if (first) {
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
- first = FALSE;
- }
+ 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, "; ");
+ }
+
+ 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);
- if(parent_tree){
- item = proto_tree_add_item(parent_tree, proto_ndmp, tvb, offset, size, FALSE);
- tree = proto_item_add_subtree(item, ett_ndmp);
+ if (is_tcp) {
+ show_rpc_fraginfo(tvb, frag_tvb, ndmp_tree, rpc_rm,
+ ipfd_head, pinfo);
}
+ }
+
+ /*
+ * 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;
+}
+
+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) {
/*
- * Catch the ReportedBoundsError exception; if this
- * particular message happens to get a ReportedBoundsError
- * exception, that doesn't mean that we should stop
- * dissecting NDMP messages within this frame or chunk
- * of reassembled data.
- *
- * If it gets a BoundsError, we can stop, as there's
- * nothing more to see, so we just re-throw it.
+ * Process this fragment.
*/
- saved_proto = pinfo->current_proto;
- TRY {
- /* We cannot 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);
- }
- CATCH(BoundsError) {
- RETHROW;
+ 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;
}
- CATCH(ReportedBoundsError) {
- if (check_col(pinfo->cinfo, COL_INFO)) {
- col_append_str(pinfo->cinfo, COL_INFO,
- "[Malformed Packet]");
- }
- proto_tree_add_protocol_format(parent_tree,
- proto_malformed, tvb, 0, 0,
- "[Malformed Packet: %s]", pinfo->current_proto);
- pinfo->current_proto = saved_proto;
+ if (len == 0) {
+ /*
+ * It's not NDMP. Stop processing.
+ */
+ break;
}
- ENDTRY;
- offset += size;
- } while(offset<(int)tvb_reported_length(tvb));
-}
-
-
+ 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 }},
{ &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_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, "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