* Routines for NDMP dissection
* 2001 Ronnie Sahlberg (see AUTHORS for email)
*
- * $Id: packet-ndmp.c,v 1.20 2002/06/05 11:32:14 sahlberg Exp $
+ * $Id: packet-ndmp.c,v 1.24 2003/04/21 08:13:18 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>
{0, NULL}
};
-
static int
dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
proto_tree *tree, guint32 seq _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;
}
"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;
/* 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 */
return offset;
}
-
+
static int
dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, guint32 seq _U_)
proto_tree *tree)
{
guint type;
-
+
type=tvb_get_ntohl(tvb,offset);
/* auth type */
offset = dissect_rpc_string(tvb, tree,
hf_ndmp_auth_password, offset, NULL);
-
+
break;
case NDMP_AUTH_MD5:
/* auth id */
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;
}
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:
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, 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;
}
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;
}
} 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)")
);
}
if(tree){
- cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
+ cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
msg_vals[i].strptr);
cmd_tree = proto_item_add_subtree(cmd_item, ett_ndmp);
}
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)
+ guint32 rpc_rm, gboolean first_pdu)
{
int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
guint32 size;
return TRUE;
}
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ 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);
+ 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,
{
int offset = 0;
int len;
+ gboolean first_pdu = TRUE;
while (tvb_reported_length_remaining(tvb, offset) != 0) {
/*
*/
len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
dissect_ndmp_message, FALSE, proto_ndmp, ett_ndmp,
- ndmp_defragment);
+ ndmp_defragment, first_pdu);
+ first_pdu = FALSE;
if (len < 0) {
/*
* We need more data from the TCP stream for
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 */