aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--Makefile.common3
-rw-r--r--epan/Makefile.common3
-rw-r--r--packet-mq-pcf.c318
-rw-r--r--packet-mq.c1938
-rw-r--r--packet-mq.h36
6 files changed, 1549 insertions, 750 deletions
diff --git a/AUTHORS b/AUTHORS
index 322327df58..cffef98170 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2072,6 +2072,7 @@ Ryuji Somegawa <ryuji-so [AT] is.aist-nara.ac.jp> {
metatech <metatech [AT] flashmail.com> {
IBM WebSphere MQ protocol support
+ IBM MQ Programmable Command Formats protocol support
Initial BEA Tuxedo protocol support
}
diff --git a/Makefile.common b/Makefile.common
index fbea925cb4..4279572f3b 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -3,7 +3,7 @@
# a) common to both files and
# b) portable between both files
#
-# $Id: Makefile.common,v 1.40 2004/04/29 22:40:20 sahlberg Exp $
+# $Id: Makefile.common,v 1.41 2004/05/01 21:18:09 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -131,6 +131,7 @@ DISSECTOR_INCLUDES = \
packet-llc.h \
packet-mip6.h \
packet-mount.h \
+ packet-mq.h \
packet-mrdisc.h \
packet-msnip.h \
packet-mtp3.h \
diff --git a/epan/Makefile.common b/epan/Makefile.common
index fc7eb75616..00375e5cc1 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -3,7 +3,7 @@
# a) common to both files and
# b) portable between both files
#
-# $Id: Makefile.common,v 1.20 2004/04/30 17:07:21 obiot Exp $
+# $Id: Makefile.common,v 1.21 2004/05/01 21:18:10 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -308,6 +308,7 @@ DISSECTOR_SRC = \
../packet-mpeg1.c \
../packet-mpls.c \
../packet-mq.c \
+ ../packet-mq-pcf.c \
../packet-mrdisc.c \
../packet-msdp.c \
../packet-msn-messenger.c \
diff --git a/packet-mq-pcf.c b/packet-mq-pcf.c
new file mode 100644
index 0000000000..6528e8f42a
--- /dev/null
+++ b/packet-mq-pcf.c
@@ -0,0 +1,318 @@
+/* packet-mq-pcf.c
+ * Routines for IBM WebSphere MQ PCF packet dissection
+ *
+ * metatech <metatech@flashmail.com>
+ *
+ * $Id: packet-mq-pcf.c,v 1.1 2004/05/01 21:18:09 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.
+ */
+
+/* MQ PCF in a nutshell
+*
+* The MQ Programmable Command Formats API allows remotely configuring a queue manager.
+*
+* MQ PCF documentation is called "WebSphere MQ Programmable Command Formats and Administration Interface"
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+#include "packet-mq.h"
+
+static int proto_mqpcf = -1;
+static int hf_mqpcf_cfh_type = -1;
+static int hf_mqpcf_cfh_length = -1;
+static int hf_mqpcf_cfh_version = -1;
+static int hf_mqpcf_cfh_command = -1;
+static int hf_mqpcf_cfh_msgseqnumber = -1;
+static int hf_mqpcf_cfh_control = -1;
+static int hf_mqpcf_cfh_compcode = -1;
+static int hf_mqpcf_cfh_reason = -1;
+static int hf_mqpcf_cfh_paramcount = -1;
+
+static gint ett_mqpcf = -1;
+static gint ett_mqpcf_cfh = -1;
+
+#define MQ_FMT_ADMIN "MQADMIN "
+#define MQ_FMT_EVENT "MQEVENT "
+#define MQ_FMT_PCF "MQPCF "
+
+#define MQ_ENC_INTEGER_NORMAL 0x00000001
+#define MQ_ENC_INTEGER_REVERSED 0x00000002
+
+#define MQ_CMD_NONE 0
+#define MQ_CMD_CHANGE_Q_MGR 1
+#define MQ_CMD_INQUIRE_Q_MGR 2
+#define MQ_CMD_CHANGE_PROCESS 3
+#define MQ_CMD_COPY_PROCESS 4
+#define MQ_CMD_CREATE_PROCESS 5
+#define MQ_CMD_DELETE_PROCESS 6
+#define MQ_CMD_INQUIRE_PROCESS 7
+#define MQ_CMD_CHANGE_Q 8
+#define MQ_CMD_CLEAR_Q 9
+#define MQ_CMD_COPY_Q 10
+#define MQ_CMD_CREATE_Q 11
+#define MQ_CMD_DELETE_Q 12
+#define MQ_CMD_INQUIRE_Q 13
+#define MQ_CMD_RESET_Q_STATS 17
+#define MQ_CMD_INQUIRE_Q_NAMES 18
+#define MQ_CMD_INQUIRE_PROCESS_NAMES 19
+#define MQ_CMD_INQUIRE_CHANNEL_NAMES 20
+#define MQ_CMD_CHANGE_CHANNEL 21
+#define MQ_CMD_COPY_CHANNEL 22
+#define MQ_CMD_CREATE_CHANNEL 23
+#define MQ_CMD_DELETE_CHANNEL 24
+#define MQ_CMD_INQUIRE_CHANNEL 25
+#define MQ_CMD_PING_CHANNEL 26
+#define MQ_CMD_RESET_CHANNEL 27
+#define MQ_CMD_START_CHANNEL 28
+#define MQ_CMD_STOP_CHANNEL 29
+#define MQ_CMD_START_CHANNEL_INIT 30
+#define MQ_CMD_START_CHANNEL_LISTENER 31
+#define MQ_CMD_CHANGE_NAMELIST 32
+#define MQ_CMD_COPY_NAMELIST 33
+#define MQ_CMD_CREATE_NAMELIST 34
+#define MQ_CMD_DELETE_NAMELIST 35
+#define MQ_CMD_INQUIRE_NAMELIST 36
+#define MQ_CMD_INQUIRE_NAMELIST_NAMES 37
+#define MQ_CMD_ESCAPE 38
+#define MQ_CMD_RESOLVE_CHANNEL 39
+#define MQ_CMD_PING_Q_MGR 40
+#define MQ_CMD_INQUIRE_Q_STATUS 41
+#define MQ_CMD_INQUIRE_CHANNEL_STATUS 42
+#define MQ_CMD_CONFIG_EVENT 43
+#define MQ_CMD_Q_MGR_EVENT 44
+#define MQ_CMD_PERFM_EVENT 45
+#define MQ_CMD_CHANNEL_EVENT 46
+#define MQ_CMD_DELETE_PUBLICATION 60
+#define MQ_CMD_DEREGISTER_PUBLISHER 61
+#define MQ_CMD_DEREGISTER_SUBSCRIBER 62
+#define MQ_CMD_PUBLISH 63
+#define MQ_CMD_REGISTER_PUBLISHER 64
+#define MQ_CMD_REGISTER_SUBSCRIBER 65
+#define MQ_CMD_REQUEST_UPDATE 66
+#define MQ_CMD_BROKER_INTERNAL 67
+#define MQ_CMD_INQUIRE_CLUSTER_Q_MGR 70
+#define MQ_CMD_RESUME_Q_MGR_CLUSTER 71
+#define MQ_CMD_SUSPEND_Q_MGR_CLUSTER 72
+#define MQ_CMD_REFRESH_CLUSTER 73
+#define MQ_CMD_RESET_CLUSTER 74
+#define MQ_CMD_REFRESH_SECURITY 78
+#define MQ_CMD_CHANGE_AUTH_INFO 79
+#define MQ_CMD_COPY_AUTH_INFO 80
+#define MQ_CMD_CREATE_AUTH_INFO 81
+#define MQ_CMD_DELETE_AUTH_INFO 82
+#define MQ_CMD_INQUIRE_AUTH_INFO 83
+#define MQ_CMD_INQUIRE_AUTH_INFO_NAMES 84
+
+#define MQ_TEXT_CFH "MQ Command Format Header"
+
+static const value_string mqpcf_opcode_vals[] = {
+ { MQ_CMD_NONE, "NONE" },
+ { MQ_CMD_CHANGE_Q_MGR, "CHANGE_Q_MGR" },
+ { MQ_CMD_INQUIRE_Q_MGR, "INQUIRE_Q_MGR" },
+ { MQ_CMD_CHANGE_PROCESS, "CHANGE_PROCESS" },
+ { MQ_CMD_COPY_PROCESS, "COPY_PROCESS" },
+ { MQ_CMD_CREATE_PROCESS, "CREATE_PROCESS" },
+ { MQ_CMD_DELETE_PROCESS, "DELETE_PROCESS" },
+ { MQ_CMD_INQUIRE_PROCESS, "INQUIRE_PROCESS" },
+ { MQ_CMD_CHANGE_Q, "CHANGE_Q" },
+ { MQ_CMD_CLEAR_Q, "CLEAR_Q" },
+ { MQ_CMD_COPY_Q, "COPY_Q" },
+ { MQ_CMD_CREATE_Q, "CREATE_Q" },
+ { MQ_CMD_DELETE_Q, "DELETE_Q" },
+ { MQ_CMD_INQUIRE_Q, "INQUIRE_Q" },
+ { MQ_CMD_RESET_Q_STATS, "RESET_Q_STATS" },
+ { MQ_CMD_INQUIRE_Q_NAMES, "INQUIRE_Q_NAMES" },
+ { MQ_CMD_INQUIRE_PROCESS_NAMES, "INQUIRE_PROCESS_NAMES" },
+ { MQ_CMD_INQUIRE_CHANNEL_NAMES, "INQUIRE_CHANNEL_NAMES" },
+ { MQ_CMD_CHANGE_CHANNEL, "CHANGE_CHANNEL" },
+ { MQ_CMD_COPY_CHANNEL, "COPY_CHANNEL" },
+ { MQ_CMD_CREATE_CHANNEL, "CREATE_CHANNEL" },
+ { MQ_CMD_DELETE_CHANNEL, "DELETE_CHANNEL" },
+ { MQ_CMD_INQUIRE_CHANNEL, "INQUIRE_CHANNEL" },
+ { MQ_CMD_PING_CHANNEL, "PING_CHANNEL" },
+ { MQ_CMD_RESET_CHANNEL, "RESET_CHANNEL" },
+ { MQ_CMD_START_CHANNEL, "START_CHANNEL" },
+ { MQ_CMD_STOP_CHANNEL, "STOP_CHANNEL" },
+ { MQ_CMD_START_CHANNEL_INIT, "START_CHANNEL_INIT" },
+ { MQ_CMD_START_CHANNEL_LISTENER, "START_CHANNEL_LISTENER" },
+ { MQ_CMD_CHANGE_NAMELIST, "CHANGE_NAMELIST" },
+ { MQ_CMD_CREATE_NAMELIST, "CREATE_NAMELIST" },
+ { MQ_CMD_DELETE_NAMELIST, "DELETE_NAMELIST" },
+ { MQ_CMD_INQUIRE_NAMELIST, "INQUIRE_NAMELIST" },
+ { MQ_CMD_INQUIRE_NAMELIST_NAMES, "INQUIRE_NAMELIST_NAMES" },
+ { MQ_CMD_ESCAPE, "ESCAPE" },
+ { MQ_CMD_RESOLVE_CHANNEL, "RESOLVE_CHANNEL" },
+ { MQ_CMD_PING_Q_MGR, "PING_Q_MGR" },
+ { MQ_CMD_INQUIRE_Q_STATUS, "INQUIRE_Q_STATUS" },
+ { MQ_CMD_INQUIRE_CHANNEL_STATUS, "INQUIRE_CHANNEL_STATUS" },
+ { MQ_CMD_CONFIG_EVENT, "CONFIG_EVENT" },
+ { MQ_CMD_Q_MGR_EVENT, "Q_MGR_EVENT" },
+ { MQ_CMD_PERFM_EVENT, "PERFM_EVENT" },
+ { MQ_CMD_CHANNEL_EVENT, "CHANNEL_EVENT" },
+ { MQ_CMD_DELETE_PUBLICATION, "DELETE_PUBLICATION" },
+ { MQ_CMD_DEREGISTER_PUBLISHER, "DEREGISTER_PUBLISHER" },
+ { MQ_CMD_DEREGISTER_SUBSCRIBER, "DEREGISTER_SUBSCRIBER" },
+ { MQ_CMD_PUBLISH, "PUBLISH" },
+ { MQ_CMD_REGISTER_PUBLISHER, "REGISTER_PUBLISHER" },
+ { MQ_CMD_REGISTER_SUBSCRIBER, "REGISTER_SUBSCRIBER" },
+ { MQ_CMD_REQUEST_UPDATE, "REQUEST_UPDATE" },
+ { MQ_CMD_BROKER_INTERNAL, "BROKER_INTERNAL" },
+ { MQ_CMD_INQUIRE_CLUSTER_Q_MGR, "INQUIRE_CLUSTER_Q_MGR" },
+ { MQ_CMD_RESUME_Q_MGR_CLUSTER, "RESUME_Q_MGR_CLUSTER" },
+ { MQ_CMD_SUSPEND_Q_MGR_CLUSTER, "SUSPEND_Q_MGR_CLUSTER" },
+ { MQ_CMD_REFRESH_CLUSTER, "REFRESH_CLUSTER" },
+ { MQ_CMD_REFRESH_SECURITY, "REFRESH_SECURITY" },
+ { MQ_CMD_CHANGE_AUTH_INFO, "CHANGE_AUTH_INFO" },
+ { MQ_CMD_COPY_AUTH_INFO, "COPY_AUTH_INFO" },
+ { MQ_CMD_CREATE_AUTH_INFO, "CREATE_AUTH_INFO" },
+ { MQ_CMD_DELETE_AUTH_INFO, "DELETE_AUTH_INFO" },
+ { MQ_CMD_INQUIRE_AUTH_INFO, "INQUIRE_AUTH_INFO" },
+ { MQ_CMD_INQUIRE_AUTH_INFO_NAMES, "INQUIRE_AUTH_INFO_NAMES" },
+ { 0, NULL }
+};
+
+static guint32 tvb_get_guint32_endian(tvbuff_t *a_tvb, gint a_iOffset, gboolean a_bLittleEndian)
+{
+ guint32 iResult;
+ if (a_bLittleEndian)
+ iResult = tvb_get_letohl(a_tvb, a_iOffset);
+ else
+ iResult = tvb_get_ntohl(a_tvb, a_iOffset);
+ return iResult;
+}
+
+static void
+dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *mq_tree = NULL;
+ proto_tree *mqroot_tree = NULL;
+ proto_item *ti = NULL;
+ gint offset = 0;
+ struct mqinfo* mqinfo = pinfo->private_data;
+ gboolean bLittleEndian;
+ bLittleEndian = ((mqinfo->encoding & MQ_ENC_INTEGER_REVERSED) != 0) ? TRUE : FALSE;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQ PCF");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO);
+ if (tvb_length(tvb) >= 36)
+ {
+ gint iSizeMQCFH = 36;
+ guint32 iCommand = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(iCommand, mqpcf_opcode_vals, "Unknown (0x%02x)"));
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, FALSE);
+ proto_item_append_text(ti, " (%s)", val_to_str(iCommand, mqpcf_opcode_vals, "Unknown (0x%02x)"));
+ mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);
+
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMQCFH, MQ_TEXT_CFH);
+ mq_tree = proto_item_add_subtree(ti, ett_mqpcf_cfh);
+
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type, tvb, offset + 0, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_msgseqnumber, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control, tvb, offset + 20, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode, tvb, offset + 24, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason, tvb, offset + 28, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mqpcf_cfh_paramcount, tvb, offset + 32, 4, bLittleEndian);
+ }
+ offset += iSizeMQCFH;
+ }
+}
+
+static gboolean
+dissect_mqpcf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ if (tvb_length(tvb) >= 36)
+ {
+ struct mqinfo* mqinfo = pinfo->private_data;
+ if (strncmp((const char*)mqinfo->format, MQ_FMT_ADMIN, 8) == 0
+ || strncmp((const char*)mqinfo->format, MQ_FMT_EVENT, 8) == 0
+ || strncmp((const char*)mqinfo->format, MQ_FMT_PCF, 8) == 0)
+ {
+ /* Dissect the packet */
+ dissect_mqpcf(tvb, pinfo, tree);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+proto_register_mqpcf(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_mqpcf_cfh_type,
+ { "Type", "mqpcf.cfh.type", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH type", HFILL }},
+
+ { &hf_mqpcf_cfh_length,
+ { "Length", "mqpcf.cfh.length", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH length", HFILL }},
+
+ { &hf_mqpcf_cfh_version,
+ { "Version", "mqpcf.cfh.version", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH version", HFILL }},
+
+ { &hf_mqpcf_cfh_command,
+ { "Command", "mqpcf.cfh.command", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH command", HFILL }},
+
+ { &hf_mqpcf_cfh_msgseqnumber,
+ { "Message sequence number", "mqpcf.cfh.msgseqnumber", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH message sequence number", HFILL }},
+
+ { &hf_mqpcf_cfh_control,
+ { "Control", "mqpcf.cfh.control", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH control", HFILL }},
+
+ { &hf_mqpcf_cfh_compcode,
+ { "Completion code", "mqpcf.cfh.compcode", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH completion code", HFILL }},
+
+ { &hf_mqpcf_cfh_reason,
+ { "Reason code", "mqpcf.cfh.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH reason code", HFILL }},
+
+ { &hf_mqpcf_cfh_paramcount,
+ { "Parameter count", "mqpcf.cfh.paramcount", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH parameter count", HFILL }}
+ };
+ static gint *ett[] = {
+ &ett_mqpcf,
+ &ett_mqpcf_cfh,
+ };
+
+ proto_mqpcf = proto_register_protocol("WebSphere MQ Programmable Command Formats", "MQ PCF", "mqpcf");
+ proto_register_field_array(proto_mqpcf, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_mqpcf(void)
+{
+ heur_dissector_add("mq", dissect_mqpcf_heur, proto_mqpcf);
+}
diff --git a/packet-mq.c b/packet-mq.c
index 064be735f3..983b1f2a5c 100644
--- a/packet-mq.c
+++ b/packet-mq.c
@@ -3,7 +3,7 @@
*
* metatech <metatech@flashmail.com>
*
- * $Id: packet-mq.c,v 1.4 2004/04/17 20:58:49 guy Exp $
+ * $Id: packet-mq.c,v 1.5 2004/05/01 21:18:09 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -28,7 +28,7 @@
*
* IBM WebSphere MQ (formerly IBM MQSeries) is an asynchronous proprietary messaging middleware that is based on message queues.
* MQ can run on more than 35 platforms, amongst which UNIX, Windows and mainframes.
-* MQ can be transported on top of TCP, UDP, NetBIOS, SPX, SNA LU 6.2, DECnet.
+* MQ can be transported on top of TCP, UDP, HTTP, NetBIOS, SPX, SNA LU 6.2, DECnet.
* MQ has language bindings for C, C++, Java, .NET, COBOL, PL/I, OS/390 assembler, TAL, Visual Basic.
*
* The basic MQ topology is on one side the queue manager which hosts the queues. On the other side the
@@ -54,15 +54,15 @@
* TSH MSH XQH MD [ PAYLOAD ]
* TSH [OD] MD [ GMO ^ PMO ] [ [XQH MD] PAYLOAD ]
* TSH [ SPQU ^ SPPU ^ SPGU ^ SPAU [ SPQI ^ SPQO ^ SPPI ^ SPPO ^ SPGI ^ SPGO ^ SPAI ^ SPAO]]
+* TSH [ XA ] [ XINFO | XID ]
* where PAYLOAD = [ DH ] [ DLH ] [ MDE ] BUFF
*
* This dissector is a beta version. To be improved
-* - Merged packets do not work very well.
* - Translate the integers/flags into their descriptions
* - Find the semantics of the unknown fields
* - Display EBCDIC strings as ASCII
* - Packets which structures built on different platforms
-* - XA protocol
+* - Reassembly of MQ segments
*/
#ifdef HAVE_CONFIG_H
@@ -72,6 +72,9 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>
+#include "prefs.h"
+#include "packet-tcp.h"
+#include "packet-mq.h"
static int proto_mq = -1;
static int hf_mq_tsh_structid = -1;
@@ -83,12 +86,7 @@ static int hf_mq_tsh_reserved = -1;
static int hf_mq_tsh_luwid = -1;
static int hf_mq_tsh_encoding = -1;
static int hf_mq_tsh_ccsid = -1;
-static int hf_mq_tsh_unknown4 = -1;
-static int hf_mq_tsh_length = -1;
-static int hf_mq_tsh_completioncode = -1;
-static int hf_mq_tsh_reasoncode = -1;
-static int hf_mq_tsh_statuscode = -1;
-static int hf_mq_tsh_queuehandle = -1;
+static int hf_mq_tsh_padding = -1;
static int hf_mq_tsh_tcf_confirmreq = -1;
static int hf_mq_tsh_tcf_error = -1;
static int hf_mq_tsh_tcf_reqclose = -1;
@@ -97,6 +95,10 @@ static int hf_mq_tsh_tcf_first = -1;
static int hf_mq_tsh_tcf_last = -1;
static int hf_mq_tsh_tcf_reqacc = -1;
static int hf_mq_tsh_tcf_dlq = -1;
+static int hf_mq_api_replylength = -1;
+static int hf_mq_api_completioncode = -1;
+static int hf_mq_api_reasoncode = -1;
+static int hf_mq_api_objecthandle = -1;
static int hf_mq_msh_structid = -1;
static int hf_mq_msh_seqnum = -1;
static int hf_mq_msh_datalength = -1;
@@ -180,7 +182,10 @@ static int hf_mq_spi_options_syncpoint = -1;
static int hf_mq_spi_options_deferred = -1;
static int hf_mq_put_length = -1;
static int hf_mq_open_options = -1;
+static int hf_mq_ping_length = -1;
static int hf_mq_ping_buffer = -1;
+static int hf_mq_status_length = -1;
+static int hf_mq_status_code = -1;
static int hf_mq_od_structid = -1;
static int hf_mq_od_version = -1;
static int hf_mq_od_objecttype = -1;
@@ -292,10 +297,31 @@ static int hf_mq_head_ccsid = -1;
static int hf_mq_head_format = -1;
static int hf_mq_head_flags = -1;
static int hf_mq_head_struct = -1;
+static int hf_mq_xa_length = -1;
+static int hf_mq_xa_returnvalue = -1;
+static int hf_mq_xa_tmflags = -1;
+static int hf_mq_xa_rmid = -1;
+static int hf_mq_xa_count = -1;
+static int hf_mq_xa_tmflags_join = -1;
+static int hf_mq_xa_tmflags_endrscan = -1;
+static int hf_mq_xa_tmflags_startrscan = -1;
+static int hf_mq_xa_tmflags_suspend = -1;
+static int hf_mq_xa_tmflags_success = -1;
+static int hf_mq_xa_tmflags_resume = -1;
+static int hf_mq_xa_tmflags_fail = -1;
+static int hf_mq_xa_tmflags_onephase = -1;
+static int hf_mq_xa_xid_formatid = -1;
+static int hf_mq_xa_xid_globalxid_length = -1;
+static int hf_mq_xa_xid_brq_length = -1;
+static int hf_mq_xa_xid_globalxid = -1;
+static int hf_mq_xa_xid_brq = -1;
+static int hf_mq_xa_xainfo_length = -1;
+static int hf_mq_xa_xainfo_value = -1;
static gint ett_mq = -1;
static gint ett_mq_tsh = -1;
static gint ett_mq_tsh_tcf = -1;
+static gint ett_mq_api = -1;
static gint ett_mq_msh = -1;
static gint ett_mq_xqh = -1;
static gint ett_mq_id = -1;
@@ -310,6 +336,7 @@ static gint ett_mq_spi_options = -1;
static gint ett_mq_put = -1;
static gint ett_mq_open = -1;
static gint ett_mq_ping = -1;
+static gint ett_mq_status = -1;
static gint ett_mq_od = -1;
static gint ett_mq_or = -1;
static gint ett_mq_rr = -1;
@@ -321,11 +348,26 @@ static gint ett_mq_dh = -1;
static gint ett_mq_gmo = -1;
static gint ett_mq_pmo = -1;
static gint ett_mq_head = -1; /* Factorisation of common Header structure items (DH, MDE, CIH, IIH, RFH, RMH, WIH */
+static gint ett_mq_xa = -1;
+static gint ett_mq_xa_tmflags = -1;
+static gint ett_mq_xa_xid = -1;
+static gint ett_mq_xa_info = -1;
-static dissector_handle_t mq_handle;
+static dissector_handle_t mq_tcp_handle;
+static dissector_handle_t mq_spx_handle;
static dissector_handle_t data_handle;
+static heur_dissector_list_t mq_heur_subdissector_list;
+
+static gboolean mq_desegment = TRUE;
+
#define MQ_PORT_TCP 1414
+#define MQ_SOCKET_SPX 0x5E86
+
+#define MQ_XPT_TCP 0x02
+#define MQ_XPT_NETBIOS 0x03
+#define MQ_XPT_SPX 0x04
+#define MQ_XPT_HTTP 0x07
#define MQ_STRUCTID_NULL 0x00000000
#define MQ_STRUCTID_CIH 0x43494820
@@ -504,6 +546,44 @@ static dissector_handle_t data_handle;
#define MQ_STATUS_E_TERMINATED_BY_REMOTE_EXIT 0x17
#define MQ_STATUS_E_SSL_REMOTE_BAD_CIPHER 0x18
+/* These errors codes are documented in javax.transaction.xa.XAException */
+#define MQ_XA_RBROLLBACK 100
+#define MQ_XA_RBCOMMFAIL 101
+#define MQ_XA_RBDEADLOCK 102
+#define MQ_XA_RBINTEGRITY 103
+#define MQ_XA_RBOTHER 104
+#define MQ_XA_RBPROTO 105
+#define MQ_XA_RBTIMEOUT 106
+#define MQ_XA_RBTRANSIENT 107
+#define MQ_XA_RBEND 107
+#define MQ_XA_NOMIGRATE 9
+#define MQ_XA_HEURHAZ 8
+#define MQ_XA_HEURCOM 7
+#define MQ_XA_HEURRB 6
+#define MQ_XA_HEURMIX 5
+#define MQ_XA_RETRY 4
+#define MQ_XA_RDONLY 3
+#define MQ_XA_OK 0
+#define MQ_XAER_ASYNC -2
+#define MQ_XAER_RMERR -3
+#define MQ_XAER_NOTA -4
+#define MQ_XAER_INVAL -5
+#define MQ_XAER_PROTO -6
+#define MQ_XAER_RMFAIL -7
+#define MQ_XAER_DUPID -8
+#define MQ_XAER_OUTSIDE -9
+
+/* These flags are documented in javax.transaction.xa.XAResource */
+#define MQ_XA_TMNOFLAGS 0
+#define MQ_XA_TMJOIN 0x200000
+#define MQ_XA_TMENDRSCAN 0x800000
+#define MQ_XA_TMSTARTRSCAN 0x1000000
+#define MQ_XA_TMSUSPEND 0x2000000
+#define MQ_XA_TMSUCCESS 0x4000000
+#define MQ_XA_TMRESUME 0x8000000
+#define MQ_XA_TMFAIL 0x20000000
+#define MQ_XA_TMONEPHASE 0x40000000
+
#define MQ_PMRF_NONE 0x00
#define MQ_PMRF_MSG_ID 0x01
#define MQ_PMRF_CORREL_ID 0x02
@@ -514,6 +594,7 @@ static dissector_handle_t data_handle;
/* MQ structures */
/* Undocumented structures */
#define MQ_TEXT_TSH "Transmission Segment Header"
+#define MQ_TEXT_API "API Header"
#define MQ_TEXT_ID "Initial Data"
#define MQ_TEXT_UID "User Id Data"
#define MQ_TEXT_MSH "Message Segment Header"
@@ -522,7 +603,11 @@ static dissector_handle_t data_handle;
#define MQ_TEXT_PUT "MQPUT/MQGET"
#define MQ_TEXT_OPEN "MQOPEN/MQCLOSE"
#define MQ_TEXT_PING "PING"
+#define MQ_TEXT_STAT "STATUS"
#define MQ_TEXT_SPI "SPI"
+#define MQ_TEXT_XA "XA"
+#define MQ_TEXT_XID "Xid"
+#define MQ_TEXT_XINF "XA_info"
/* Documented structures with structid */
#define MQ_TEXT_CIH "CICS bridge Header"
@@ -635,6 +720,35 @@ static const value_string mq_status_vals[] = {
{ 0, NULL }
};
+static const value_string mq_xaer_vals[] = {
+ { MQ_XA_RBROLLBACK, "XA_RBROLLBACK" },
+ { MQ_XA_RBCOMMFAIL, "XA_RBCOMMFAIL" },
+ { MQ_XA_RBDEADLOCK, "XA_RBDEADLOCK" },
+ { MQ_XA_RBINTEGRITY, "XA_RBINTEGRITY" },
+ { MQ_XA_RBOTHER, "XA_RBOTHER" },
+ { MQ_XA_RBPROTO, "XA_RBPROTO" },
+ { MQ_XA_RBTIMEOUT, "XA_RBTIMEOUT" },
+ { MQ_XA_RBTRANSIENT, "XA_RBTRANSIENT" },
+ { MQ_XA_RBEND, "XA_RBEND" },
+ { MQ_XA_NOMIGRATE, "XA_NOMIGRATE" },
+ { MQ_XA_HEURHAZ, "XA_HEURHAZ" },
+ { MQ_XA_HEURCOM, "XA_HEURCOM" },
+ { MQ_XA_HEURRB, "XA_HEURRB" },
+ { MQ_XA_HEURMIX, "XA_HEURMIX" },
+ { MQ_XA_RETRY, "XA_RETRY" },
+ { MQ_XA_RDONLY, "XA_RDONLY" },
+ { MQ_XA_OK, "XA_OK" },
+ { (guint32)MQ_XAER_ASYNC, "XAER_ASYNC" },
+ { (guint32)MQ_XAER_RMERR, "XAER_RMERR" },
+ { (guint32)MQ_XAER_NOTA, "XAER_NOTA" },
+ { (guint32)MQ_XAER_INVAL, "XAER_INVAL" },
+ { (guint32)MQ_XAER_PROTO, "XAER_PROTO" },
+ { (guint32)MQ_XAER_RMFAIL, "XAER_RMFAIL" },
+ { (guint32)MQ_XAER_DUPID, "XAER_DUPID" },
+ { (guint32)MQ_XAER_OUTSIDE, "XAER_OUTSIDE" },
+ { 0, NULL }
+};
+
static const value_string mq_structid_vals[] = {
{ MQ_STRUCTID_CIH, MQ_TEXT_CIH },
{ MQ_STRUCTID_DH, MQ_TEXT_DH },
@@ -686,6 +800,12 @@ static const value_string mq_conn_version_vals[] = {
{ 0, NULL }
};
+struct mq_msg_properties {
+ gint iOffsetEncoding; /* Message encoding */
+ gint iOffsetCcsid; /* Message character set */
+ gint iOffsetFormat; /* Message format */
+};
+
static guint32 tvb_get_guint32_endian(tvbuff_t *a_tvb, gint a_iOffset, gboolean a_bLittleEndian)
{
guint32 iResult;
@@ -715,7 +835,7 @@ static gint strip_trailing_blanks(guint8* a_string, gint a_size)
}
static gint
-dissect_mq_md(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset, gint* iOffsetFormat)
+dissect_mq_md(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, struct mq_msg_properties* tMsgProps)
{
proto_tree *mq_tree = NULL;
proto_item *ti = NULL;
@@ -725,11 +845,10 @@ dissect_mq_md(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLit
if (tvb_length_remaining(tvb, offset) >= 4)
{
structId = tvb_get_ntohl(tvb, offset);
- if ((structId == MQ_STRUCTID_MD || structId == MQ_STRUCTID_MD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 324)
+ if ((structId == MQ_STRUCTID_MD || structId == MQ_STRUCTID_MD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
{
guint32 iVersionMD = 0;
iVersionMD = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
- *iOffsetFormat = offset + 32;
/* Compute length according to version */
switch (iVersionMD)
{
@@ -737,43 +856,49 @@ dissect_mq_md(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLit
case 2: iSizeMD = 364; break;
}
- if (tree)
+ if (iSizeMD != 0 && tvb_length_remaining(tvb, offset) >= iSizeMD)
{
- ti = proto_tree_add_text(tree, tvb, offset, iSizeMD, MQ_TEXT_MD);
- mq_tree = proto_item_add_subtree(ti, ett_mq_md);
-
- proto_tree_add_item(mq_tree, hf_mq_md_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_report, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_msgtype, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_expiry, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_feedback, tvb, offset + 20, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_encoding, tvb, offset + 24, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_ccsid, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_format, tvb, offset + 32, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_priority, tvb, offset + 40, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_persistence, tvb, offset + 44, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_msgid, tvb, offset + 48, 24, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_correlid, tvb, offset + 72, 24, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_backountcount, tvb, offset + 96, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_replytoq, tvb, offset + 100, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_replytoqmgr, tvb, offset + 148, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_userid, tvb, offset + 196, 12, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_acttoken, tvb, offset + 208, 32, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_appliddata, tvb, offset + 240, 32, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_putappltype, tvb, offset + 272, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_putapplname, tvb, offset + 276, 28, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_putdate, tvb, offset + 304, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_puttime, tvb, offset + 312, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_applorigindata, tvb, offset + 320, 4, FALSE);
-
- if (iSizeMD == 364 && tvb_length_remaining(tvb, offset) >= 364)
+ tMsgProps->iOffsetEncoding = offset + 24;
+ tMsgProps->iOffsetCcsid = offset + 28;
+ tMsgProps->iOffsetFormat = offset + 32;
+ if (tree)
{
- proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 324, 24, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 348, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 352, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 356, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 360, 4, bLittleEndian);
+ ti = proto_tree_add_text(tree, tvb, offset, iSizeMD, MQ_TEXT_MD);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_md);
+
+ proto_tree_add_item(mq_tree, hf_mq_md_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_report, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgtype, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_expiry, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_feedback, tvb, offset + 20, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_encoding, tvb, offset + 24, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_ccsid, tvb, offset + 28, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_format, tvb, offset + 32, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_priority, tvb, offset + 40, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_persistence, tvb, offset + 44, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgid, tvb, offset + 48, 24, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_correlid, tvb, offset + 72, 24, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_backountcount, tvb, offset + 96, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_replytoq, tvb, offset + 100, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_replytoqmgr, tvb, offset + 148, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_userid, tvb, offset + 196, 12, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_acttoken, tvb, offset + 208, 32, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_appliddata, tvb, offset + 240, 32, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_putappltype, tvb, offset + 272, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_putapplname, tvb, offset + 276, 28, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_putdate, tvb, offset + 304, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_puttime, tvb, offset + 312, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_applorigindata, tvb, offset + 320, 4, FALSE);
+
+ if (iVersionMD >= 2)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 324, 24, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 348, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 352, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 356, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 360, 4, bLittleEndian);
+ }
}
}
}
@@ -783,14 +908,14 @@ dissect_mq_md(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLit
static gint
-dissect_mq_or(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetOR)
+dissect_mq_or(tvbuff_t *tvb, proto_tree *tree, gint offset, gint iNbrRecords, gint offsetOR)
{
proto_tree *mq_tree = NULL;
proto_item *ti = NULL;
gint iSizeOR = 0;
if (offsetOR != 0)
{
- iSizeOR += iNbrRecords * 96;
+ iSizeOR = iNbrRecords * 96;
if (tvb_length_remaining(tvb, offset) >= iSizeOR)
{
if (tree)
@@ -813,14 +938,14 @@ dissect_mq_or(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLit
}
static gint
-dissect_mq_rr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetRR)
+dissect_mq_rr(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetRR)
{
proto_tree *mq_tree = NULL;
proto_item *ti = NULL;
gint iSizeRR = 0;
if (offsetRR != 0)
{
- iSizeRR += iNbrRecords * 8;
+ iSizeRR = iNbrRecords * 8;
if (tvb_length_remaining(tvb, offset) >= iSizeRR)
{
if (tree)
@@ -843,7 +968,7 @@ dissect_mq_rr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLit
}
static gint
-dissect_mq_pmr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetPMR, guint32 recFlags)
+dissect_mq_pmr(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetPMR, guint32 recFlags)
{
proto_tree *mq_tree = NULL;
proto_item *ti = NULL;
@@ -912,7 +1037,7 @@ dissect_mq_gmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLi
if (tvb_length_remaining(tvb, offset) >= 4)
{
structId = tvb_get_ntohl(tvb, offset);
- if ((structId == MQ_STRUCTID_GMO || structId == MQ_STRUCTID_GMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 72)
+ if ((structId == MQ_STRUCTID_GMO || structId == MQ_STRUCTID_GMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
{
guint32 iVersionGMO = 0;
iVersionGMO = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
@@ -924,43 +1049,46 @@ dissect_mq_gmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLi
case 3: iSizeGMO = 100; break;
}
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- guint8* sQueue;
- sQueue = tvb_get_string(tvb, offset + 24, 48);
- if (strip_trailing_blanks(sQueue, 48) != 0)
- {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
- }
- g_free(sQueue);
- }
-
- if (tree)
+ if (iSizeGMO != 0 && tvb_length_remaining(tvb, offset) >= iSizeGMO)
{
- ti = proto_tree_add_text(tree, tvb, offset, iSizeGMO, MQ_TEXT_GMO);
- mq_tree = proto_item_add_subtree(ti, ett_mq_gmo);
-
- proto_tree_add_item(mq_tree, hf_mq_gmo_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_gmo_options, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_gmo_waitinterval, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_gmo_signal1, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_gmo_signal2, tvb, offset + 20, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_gmo_resolvedqname, tvb, offset + 24, 48, FALSE);
-
- if (iSizeGMO >= 80 && tvb_length_remaining(tvb, offset) >= 80)
+ if (check_col(pinfo->cinfo, COL_INFO))
{
- proto_tree_add_item(mq_tree, hf_mq_gmo_matchoptions, tvb, offset + 72, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_groupstatus, tvb, offset + 76, 1, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_segmentstatus, tvb, offset + 77, 1, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_segmentation, tvb, offset + 78, 1, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_reserved, tvb, offset + 79, 1, FALSE);
+ guint8* sQueue;
+ sQueue = tvb_get_string(tvb, offset + 24, 48);
+ if (strip_trailing_blanks(sQueue, 48) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
+ }
+ g_free(sQueue);
}
-
- if (iSizeGMO >= 100 && tvb_length_remaining(tvb, offset) >= 100)
+
+ if (tree)
{
- proto_tree_add_item(mq_tree, hf_mq_gmo_msgtoken, tvb, offset + 80, 16, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_gmo_returnedlength, tvb, offset + 96, 4, bLittleEndian);
+ ti = proto_tree_add_text(tree, tvb, offset, iSizeGMO, MQ_TEXT_GMO);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_gmo);
+
+ proto_tree_add_item(mq_tree, hf_mq_gmo_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_options, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_waitinterval, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_signal1, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_signal2, tvb, offset + 20, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_resolvedqname, tvb, offset + 24, 48, FALSE);
+
+ if (iVersionGMO >= 2)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_gmo_matchoptions, tvb, offset + 72, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_groupstatus, tvb, offset + 76, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_segmentstatus, tvb, offset + 77, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_segmentation, tvb, offset + 78, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_reserved, tvb, offset + 79, 1, FALSE);
+ }
+
+ if (iVersionGMO >= 3)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_gmo_msgtoken, tvb, offset + 80, 16, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_gmo_returnedlength, tvb, offset + 96, 4, bLittleEndian);
+ }
}
}
}
@@ -979,83 +1107,121 @@ dissect_mq_pmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLi
if (tvb_length_remaining(tvb, offset) >= 4)
{
structId = tvb_get_ntohl(tvb, offset);
- if ((structId == MQ_STRUCTID_PMO || structId == MQ_STRUCTID_PMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 128)
+ if ((structId == MQ_STRUCTID_PMO || structId == MQ_STRUCTID_PMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
{
guint32 iVersionPMO = 0;
- gint iNbrRecords = 0;
- guint32 iRecFlags = 0;
iVersionPMO = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
/* Compute length according to version */
switch (iVersionPMO)
{
case 1: iSizePMO = 128; break;
- case 2: iSizePMO = 152; break;
+ case 2: iSizePMO = 152;break;
}
- if (iSizePMO >= 136)
+ if (iSizePMO != 0 && tvb_length_remaining(tvb, offset) >= iSizePMO)
{
- iNbrRecords = tvb_get_guint32_endian(tvb, offset + 128, bLittleEndian);
- iRecFlags = tvb_get_guint32_endian(tvb, offset + 132, bLittleEndian);
- }
-
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- guint8* sQueue;
- sQueue = tvb_get_string(tvb, offset + 32, 48);
- if (strip_trailing_blanks(sQueue, 48) != 0)
+ gint iNbrRecords = 0;
+ guint32 iRecFlags = 0;
+ if (iVersionPMO >= 2)
{
- col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
+ iNbrRecords = tvb_get_guint32_endian(tvb, offset + 128, bLittleEndian);
+ iRecFlags = tvb_get_guint32_endian(tvb, offset + 132, bLittleEndian);
}
- g_free(sQueue);
- }
-
- if (tree)
- {
- ti = proto_tree_add_text(tree, tvb, offset, iSizePMO, MQ_TEXT_PMO);
- mq_tree = proto_item_add_subtree(ti, ett_mq_pmo);
- proto_tree_add_item(mq_tree, hf_mq_pmo_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_pmo_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_options, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_timeout, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_context, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_knowndestcount, tvb, offset + 20, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_unknowndestcount, tvb, offset + 24, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_invaliddestcount, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqname, tvb, offset + 32, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqmgrname, tvb, offset + 80, 48, FALSE);
-
- if (iSizePMO >= 152 && tvb_length_remaining(tvb, offset) >= 152)
+
+ if (check_col(pinfo->cinfo, COL_INFO))
{
- proto_tree_add_item(mq_tree, hf_mq_pmo_recspresent, tvb, offset + 128, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecfields, tvb, offset + 132, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecoffset, tvb, offset + 136, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_responserecoffset, tvb, offset + 140, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecptr, tvb, offset + 144, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_pmo_responserecptr, tvb, offset + 148, 4, bLittleEndian);
+ guint8* sQueue;
+ sQueue = tvb_get_string(tvb, offset + 32, 48);
+ if (strip_trailing_blanks(sQueue, 48) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
+ }
+ g_free(sQueue);
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, offset, iSizePMO, MQ_TEXT_PMO);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_pmo);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_options, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_timeout, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_context, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_knowndestcount, tvb, offset + 20, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_unknowndestcount, tvb, offset + 24, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_invaliddestcount, tvb, offset + 28, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqname, tvb, offset + 32, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqmgrname, tvb, offset + 80, 48, FALSE);
+
+ if (iVersionPMO >= 2)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_pmo_recspresent, tvb, offset + 128, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecfields, tvb, offset + 132, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecoffset, tvb, offset + 136, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_responserecoffset, tvb, offset + 140, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecptr, tvb, offset + 144, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_pmo_responserecptr, tvb, offset + 148, 4, bLittleEndian);
+ }
+
+ }
+ if (iNbrRecords > 0)
+ {
+ gint iOffsetPMR = 0;
+ gint iOffsetRR = 0;
+ gint iSizePMRRR = 0;
+
+ *iDistributionListSize = iNbrRecords;
+ iOffsetPMR = tvb_get_guint32_endian(tvb, offset + 136, bLittleEndian);
+ iOffsetRR = tvb_get_guint32_endian(tvb, offset + 140, bLittleEndian);
+ if ((iSizePMRRR = dissect_mq_pmr(tvb, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
+ iSizePMO += iSizePMRRR;
+ if ((iSizePMRRR = dissect_mq_rr(tvb, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetRR)) != 0)
+ iSizePMO += iSizePMRRR;
}
-
}
- if (iNbrRecords > 0)
+ }
+ }
+ return iSizePMO;
+}
+
+static gint
+dissect_mq_xid(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset)
+{
+ proto_tree *mq_tree = NULL;
+ proto_item *ti = NULL;
+ gint iSizeXid = 0;
+ if (tvb_length_remaining(tvb, offset) >= 6)
+ {
+ guint8 iXidLength = 0;
+ guint8 iBqLength = 0;
+ iXidLength = tvb_get_guint8(tvb, offset + 4);
+ iBqLength = tvb_get_guint8(tvb, offset + 5);
+ iSizeXid = 6 + iXidLength + iBqLength;
+
+ if (tvb_length_remaining(tvb, offset) >= iSizeXid)
+ {
+ if (tree)
{
- gint iOffsetPMR = 0;
- gint iOffsetRR = 0;
- gint iSizePMRRR = 0;
-
- *iDistributionListSize = iNbrRecords;
- iOffsetPMR = tvb_get_guint32_endian(tvb, offset + 136, bLittleEndian);
- iOffsetRR = tvb_get_guint32_endian(tvb, offset + 140, bLittleEndian);
- if ((iSizePMRRR = dissect_mq_pmr(tvb, pinfo, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
- iSizePMO += iSizePMRRR;
- if ((iSizePMRRR = dissect_mq_rr(tvb, pinfo, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetRR)) != 0)
- iSizePMO += iSizePMRRR;
+ ti = proto_tree_add_text(tree, tvb, offset, iSizeXid, MQ_TEXT_XID);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_xa_xid);
+
+ proto_tree_add_item(mq_tree, hf_mq_xa_xid_formatid, tvb, offset, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_xa_xid_globalxid_length, tvb, offset + 4, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xa_xid_brq_length, tvb, offset + 5, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xa_xid_globalxid, tvb, offset + 6, iXidLength, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xa_xid_brq, tvb, offset + 6 + iXidLength, iBqLength, FALSE);
}
+ iSizeXid += (4 - (iSizeXid % 4)) % 4; /* Pad for alignment with 4 byte word boundary */
+ if (tvb_length_remaining(tvb, offset) < iSizeXid) iSizeXid = 0;
}
+ else iSizeXid = 0;
}
- return iSizePMO;
+ return iSizeXid;
}
static void
-dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_mq_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *mq_tree = NULL;
proto_tree *mqroot_tree = NULL;
@@ -1070,27 +1236,36 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gboolean bPayload = FALSE;
gboolean bEBCDIC = FALSE;
gint iDistributionListSize = 0;
- gint iOffsetFormat = 0;
+ struct mq_msg_properties tMsgProps;
+ static gint iPreviousFrameNumber = -1;
if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQ");
- if (tvb_length(tvb) >= 28)
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ /* This is a trick to know whether this is the first PDU in this packet or not */
+ if (iPreviousFrameNumber != (gint) pinfo->fd->num)
+ col_clear(pinfo->cinfo, COL_INFO);
+ else
+ col_append_str(pinfo->cinfo, COL_INFO, " | ");
+ }
+ iPreviousFrameNumber = pinfo->fd->num;
+ if (tvb_length(tvb) >= 4)
{
structId = tvb_get_ntohl(tvb, offset);
- if (structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC)
+ if ((structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 28)
{
/* An MQ packet always starts with this structure*/
- gint iSizeTSH = 0;
+ gint iSizeTSH = 28;
+ guint8 iControlFlags = 0;
if (structId == MQ_STRUCTID_TSH_EBCDIC) bEBCDIC = TRUE;
opcode = tvb_get_guint8(tvb, offset + 9);
- iSizeTSH = ((opcode >= 0x80 && opcode <= 0x9F) ? 44 : 28); /* guess */
- if (opcode == MQ_TST_STATUS && tvb_length_remaining(tvb, offset) >= 36) iSizeTSH = 36;
- if (opcode == MQ_TST_PING && tvb_length_remaining(tvb, offset) >= 32) iSizeTSH = 32;
bLittleEndian = (tvb_get_guint8(tvb, offset + 8) == MQ_LITTLE_ENDIAN ? TRUE : FALSE);
iSegmentLength = tvb_get_ntohl(tvb, offset + 4);
+ iControlFlags = tvb_get_guint8(tvb, offset + 10);
if (check_col(pinfo->cinfo, COL_INFO))
{
- col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
}
if (tree)
@@ -1113,11 +1288,9 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Control flags */
{
proto_tree *mq_tree_sub = NULL;
- guint8 iControlFlags;
ti = proto_tree_add_item(mq_tree, hf_mq_tsh_controlflags, tvb, offset + 10, 1, FALSE);
mq_tree_sub = proto_item_add_subtree(ti, ett_mq_tsh_tcf);
- iControlFlags = tvb_get_guint8(tvb, offset + 10);
proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_dlq, tvb, offset + 10, 1, iControlFlags);
proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_reqacc, tvb, offset + 10, 1, iControlFlags);
@@ -1133,186 +1306,223 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(mq_tree, hf_mq_tsh_luwid, tvb, offset + 12, 8, FALSE);
proto_tree_add_item(mq_tree, hf_mq_tsh_encoding, tvb, offset + 20, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_tsh_ccsid, tvb, offset + 24, 2, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_tsh_unknown4, tvb, offset + 26, 2, FALSE);
-
- if (iSizeTSH >= 44 && tvb_length_remaining(tvb, offset) >= 44)
- {
- proto_tree_add_item(mq_tree, hf_mq_tsh_length, tvb, offset + 28, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_tsh_completioncode, tvb, offset + 32, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_tsh_reasoncode, tvb, offset + 36, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_tsh_queuehandle, tvb, offset + 40, 4, bLittleEndian);
- }
- else if (opcode == MQ_TST_STATUS && tvb_length_remaining(tvb, offset) >= 36)
- {
- proto_tree_add_item(mq_tree, hf_mq_tsh_length, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_tsh_statuscode, tvb, offset + 32, 4, bLittleEndian);
- }
- else if (opcode == MQ_TST_PING && tvb_length_remaining(tvb, offset) >= 32)
- {
- proto_tree_add_item(mq_tree, hf_mq_tsh_length, tvb, offset + 28, 4, bLittleEndian);
- }
+ proto_tree_add_item(mq_tree, hf_mq_tsh_padding, tvb, offset + 26, 2, FALSE);
}
offset += iSizeTSH;
/* Now dissect the embedded structures */
- if (tvb_length_remaining(tvb, offset) >= 4)
+ if (tvb_length_remaining(tvb, offset) >= 4)
{
structId = tvb_get_ntohl(tvb, offset);
- if ((structId == MQ_STRUCTID_MSH || structId == MQ_STRUCTID_MSH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 20)
+ if (((iControlFlags & MQ_TCF_FIRST) != 0) || opcode < 0x80)
{
- gint iSizeMSH = 20;
- iSizePayload = tvb_get_guint32_endian(tvb, offset + 16, bLittleEndian);
- bPayload = TRUE;
- if (tree)
+ /* First MQ segment (opcodes below 0x80 never span several TSH) */
+ gint iSizeAPI = 16;
+ if (opcode >= 0x80 && opcode <= 0x9F && tvb_length_remaining(tvb, offset) >= 16)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMSH, MQ_TEXT_MSH);
- mq_tree = proto_item_add_subtree(ti, ett_mq_msh);
-
- proto_tree_add_item(mq_tree, hf_mq_msh_structid, tvb, offset + 0, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_msh_seqnum, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_msh_datalength, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_msh_unknown1, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_msh_msglength, tvb, offset + 16, 4, bLittleEndian);
+ guint32 iReturnCode = 0;
+ iReturnCode = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ if (iReturnCode != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, " [RC=%d]", iReturnCode);
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeAPI, MQ_TEXT_API);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_api);
+
+ proto_tree_add_item(mq_tree, hf_mq_api_replylength, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_api_completioncode, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_api_reasoncode, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_api_objecthandle, tvb, offset + 12, 4, bLittleEndian);
+ }
+ offset += iSizeAPI;
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- offset += iSizeMSH;
- }
- else if (opcode == MQ_TST_PING && tvb_length_remaining(tvb, offset) > 0)
- {
- if (tree)
+ if ((structId == MQ_STRUCTID_MSH || structId == MQ_STRUCTID_MSH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 20)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_PING);
- mq_tree = proto_item_add_subtree(ti, ett_mq_ping);
-
- proto_tree_add_item(mq_tree, hf_mq_ping_buffer, tvb, offset, -1, FALSE);
+ gint iSizeMSH = 20;
+ iSizePayload = tvb_get_guint32_endian(tvb, offset + 16, bLittleEndian);
+ bPayload = TRUE;
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMSH, MQ_TEXT_MSH);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_msh);
+
+ proto_tree_add_item(mq_tree, hf_mq_msh_structid, tvb, offset + 0, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_msh_seqnum, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_msh_datalength, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_msh_unknown1, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_msh_msglength, tvb, offset + 16, 4, bLittleEndian);
+ }
+ offset += iSizeMSH;
}
- offset = tvb_length(tvb);
- }
- else if (opcode == MQ_TST_MQCONN && tvb_length_remaining(tvb, offset) >= 112)
- {
- gint iSizeCONN = 0;
- /* The MQCONN structure is special because it does not start with a structid */
- if (check_col(pinfo->cinfo, COL_INFO))
+ else if (opcode == MQ_TST_STATUS && tvb_length_remaining(tvb, offset) >= 8)
{
- guint8* sApplicationName;
- guint8* sQueueManager;
- sApplicationName = tvb_get_string(tvb, offset + 48, 28);
- if (strip_trailing_blanks(sApplicationName, 28) != 0)
+ /* Some status are 28 bytes long and some are 36 bytes long */
+ guint32 iStatus = 0;
+ iStatus = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
{
- col_append_fstr(pinfo->cinfo, COL_INFO, ": App=%s", sApplicationName);
+ if (iStatus != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Code=%s", val_to_str(iStatus, mq_status_vals, "Unknown (0x%08x)"));
}
- g_free(sApplicationName);
- sQueueManager = tvb_get_string(tvb, offset, 48);
- if (strip_trailing_blanks(sQueueManager, 48) != 0)
+ if (tree)
{
- col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, 8, MQ_TEXT_STAT);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_status);
+
+ proto_tree_add_item(mq_tree, hf_mq_status_length, tvb, offset, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_status_code, tvb, offset + 4, 4, bLittleEndian);
}
- g_free(sQueueManager);
+ offset += 8;
}
-
- /*iSizeCONN = ((iVersionID == 4 || iVersionID == 6) ? 120 : 112);*/ /* guess */
- /* The iVersionID is available in the previous ID segment, we should keep a state
- * Instead we rely on the segment length announced in the TSH */
- iSizeCONN = iSegmentLength - iSizeTSH;
- if (iSizeCONN != 112 && iSizeCONN != 120) iSizeCONN = 120;
-
- if (tree)
+ else if (opcode == MQ_TST_PING && tvb_length_remaining(tvb, offset) > 4)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeCONN, MQ_TEXT_CONN);
- mq_tree = proto_item_add_subtree(ti, ett_mq_conn);
-
- proto_tree_add_item(mq_tree, hf_mq_conn_queuemanager, tvb, offset, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_conn_appname, tvb, offset + 48, 28, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_conn_apptype, tvb, offset + 76, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_conn_acttoken, tvb, offset + 80, 32, FALSE);
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_PING);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_ping);
+
+ proto_tree_add_item(mq_tree, hf_mq_ping_length, tvb, offset, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_ping_buffer, tvb, offset + 4, -1, FALSE);
+ }
+ offset = tvb_length(tvb);
}
-
- if (tvb_length_remaining(tvb, offset) >= 120)
+ else if (opcode == MQ_TST_MQCONN && tvb_length_remaining(tvb, offset) > 0)
{
- if (tree)
+ gint iSizeCONN = 0;
+ /*iSizeCONN = ((iVersionID == 4 || iVersionID == 6) ? 120 : 112);*/ /* guess */
+ /* The iVersionID is available in the previous ID segment, we should keep a state
+ * Instead we rely on the segment length announced in the TSH */
+ /* The MQCONN structure is special because it does not start with a structid */
+ iSizeCONN = iSegmentLength - iSizeTSH - iSizeAPI;
+ if (iSizeCONN != 112 && iSizeCONN != 120) iSizeCONN = 0;
+
+ if (iSizeCONN != 0 && tvb_length_remaining(tvb, offset) >= iSizeCONN)
{
- proto_tree_add_item(mq_tree, hf_mq_conn_version, tvb, offset + 112, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_conn_options, tvb, offset + 116, 4, bLittleEndian);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ guint8* sApplicationName;
+ guint8* sQueueManager;
+ sApplicationName = tvb_get_string(tvb, offset + 48, 28);
+ if (strip_trailing_blanks(sApplicationName, 28) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": App=%s", sApplicationName);
+ }
+ g_free(sApplicationName);
+ sQueueManager = tvb_get_string(tvb, offset, 48);
+ if (strip_trailing_blanks(sQueueManager, 48) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
+ }
+ g_free(sQueueManager);
+ }
+
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeCONN, MQ_TEXT_CONN);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_conn);
+
+ proto_tree_add_item(mq_tree, hf_mq_conn_queuemanager, tvb, offset, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_conn_appname, tvb, offset + 48, 28, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_conn_apptype, tvb, offset + 76, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_conn_acttoken, tvb, offset + 80, 32, FALSE);
+
+ if (iSizeCONN >= 120)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_conn_version, tvb, offset + 112, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_conn_options, tvb, offset + 116, 4, bLittleEndian);
+ }
+ }
+ offset += iSizeCONN;
}
}
- offset += iSizeCONN;
- }
- else if ((opcode == MQ_TST_MQINQ || opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET) && tvb_length_remaining(tvb, offset) >= 12)
- {
- gint iSizeINQ = 0;
- /* The MQINQ/MQSET structure is special because it does not start with a structid */
- iSizeINQ = iSegmentLength - iSizeTSH;
- if (tvb_length_remaining(tvb, offset) >= iSizeINQ)
+ else if ((opcode == MQ_TST_MQINQ || opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET) && tvb_length_remaining(tvb, offset) >= 12)
{
+ /* The MQINQ/MQSET structure is special because it does not start with a structid */
+ gint iNbSelectors = 0;
+ gint iNbIntegers = 0;
+ gint iCharLen = 0;
+ gint iOffsetINQ = 0;
+ gint iSelector = 0;
+
+ iNbSelectors = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
+ iNbIntegers = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
+ iCharLen = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
+
if (tree)
{
- gint iNbSelectors = 0;
- gint iNbIntegers = 0;
- gint iCharLen = 0;
- gint iOffsetINQ = 0;
- gint iSelector = 0;
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeINQ, MQ_TEXT_INQ);
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_INQ);
mq_tree = proto_item_add_subtree(ti, ett_mq_inq);
-
- iNbSelectors = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
- iNbIntegers = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
- iCharLen = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
-
+
proto_tree_add_item(mq_tree, hf_mq_inq_nbsel, tvb, offset, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_inq_nbint, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_inq_charlen, tvb, offset + 8, 4, bLittleEndian);
- iOffsetINQ = 12;
- if (tvb_length_remaining(tvb, offset) >= iNbSelectors * 4)
+ }
+ iOffsetINQ = 12;
+ if (tvb_length_remaining(tvb, offset + iOffsetINQ) >= iNbSelectors * 4)
+ {
+ if (tree)
{
for (iSelector = 0; iSelector < iNbSelectors; iSelector++)
{
- proto_tree_add_item(mq_tree, hf_mq_inq_sel, tvb, offset + iOffsetINQ, 4, bLittleEndian);
- iOffsetINQ += 4;
+ proto_tree_add_item(mq_tree, hf_mq_inq_sel, tvb, offset + iOffsetINQ + iSelector * 4, 4, bLittleEndian);
}
- if (opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET)
+ }
+ iOffsetINQ += iNbSelectors * 4;
+ if (opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET)
+ {
+ gint iSizeINQValues = 0;
+ iSizeINQValues = iNbIntegers * 4 + iCharLen;
+ if (tvb_length_remaining(tvb, offset + iOffsetINQ) >= iSizeINQValues)
{
- gint iSizeINQValues = 0;
- iSizeINQValues = iNbIntegers * 4 + iCharLen;
- if (tvb_length_remaining(tvb, offset) >= iSizeINQValues)
+ gint iInteger = 0;
+ if (tree)
+ {
+ for (iInteger = 0; iInteger < iNbIntegers; iInteger++)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_inq_intvalue, tvb, offset + iOffsetINQ + iInteger * 4, 4, bLittleEndian);
+ }
+ }
+ iOffsetINQ += iNbIntegers * 4;
+ if (iCharLen != 0)
{
- for (iSelector = 0; iSelector < iNbIntegers; iSelector++)
+ if (tree)
{
- proto_tree_add_item(mq_tree, hf_mq_inq_intvalue, tvb, offset + iOffsetINQ, 4, bLittleEndian);
- iOffsetINQ += 4;
+ proto_tree_add_item(mq_tree, hf_mq_inq_charvalues, tvb, offset + iOffsetINQ, iCharLen, FALSE);
}
- if (iCharLen != 0)
- proto_tree_add_item(mq_tree, hf_mq_inq_charvalues, tvb, offset + iOffsetINQ, iSizeINQ - iOffsetINQ, FALSE);
}
}
}
}
- offset += iSizeINQ;
+ offset += tvb_length(tvb);
}
- }
- else if ((opcode == MQ_TST_SPI || opcode == MQ_TST_SPI_REPLY) && tvb_length_remaining(tvb, offset) >= 12)
- {
- gint iSizeSPI = 0;
- gint iOffsetSPI = 0;
- guint32 iSpiVerb = 0;
- /* The SPI structure is special because it does not start with a structid */
- iSizeSPI = iSegmentLength - iSizeTSH;
- if (tvb_length_remaining(tvb, offset) >= iSizeSPI)
+ else if ((opcode == MQ_TST_SPI || opcode == MQ_TST_SPI_REPLY) && tvb_length_remaining(tvb, offset) >= 12)
{
+ gint iOffsetSPI = 0;
+ guint32 iSpiVerb = 0;
+
iSpiVerb = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(iSpiVerb, mq_spi_verbs_vals, "Unknown (0x%08x)"));
}
-
+
if (tree)
{
ti = proto_tree_add_text(mqroot_tree, tvb, offset, 12, MQ_TEXT_SPI);
mq_tree = proto_item_add_subtree(ti, ett_mq_spi);
-
+
proto_tree_add_item(mq_tree, hf_mq_spi_verb, tvb, offset, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_spi_version, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_spi_length, tvb, offset + 8, 4, bLittleEndian);
}
-
+
offset += 12;
structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
if ((structId == MQ_STRUCTID_SPQU || structId == MQ_STRUCTID_SPAU_EBCDIC
@@ -1321,7 +1531,7 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|| structId == MQ_STRUCTID_SPAU || structId == MQ_STRUCTID_SPAU_EBCDIC)
&& tvb_length_remaining(tvb, offset) >= 12)
{
- gint iSizeMD = 0;
+ gint iSizeSPIMD = 0;
if (tree)
{
guint8* sStructId;
@@ -1329,20 +1539,20 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_text(mqroot_tree, tvb, offset, 12, (const char*)sStructId);
g_free(sStructId);
mq_tree = proto_item_add_subtree(ti, ett_mq_spi_base);
-
+
proto_tree_add_item(mq_tree, hf_mq_spi_base_structid, tvb, offset, 4, FALSE);
proto_tree_add_item(mq_tree, hf_mq_spi_base_version, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_spi_base_length, tvb, offset + 8, 4, bLittleEndian);
}
offset += 12;
structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
-
- if ((iSizeMD = dissect_mq_md(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iOffsetFormat)) != 0)
+
+ if ((iSizeSPIMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
{
gint iSizeGMO = 0;
gint iSizePMO = 0;
- offset += iSizeMD;
-
+ offset += iSizeSPIMD;
+
if ((iSizeGMO = dissect_mq_gmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset)) != 0)
{
offset += iSizeGMO;
@@ -1353,7 +1563,7 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
-
+
if ((structId == MQ_STRUCTID_SPQO || structId == MQ_STRUCTID_SPQO_EBCDIC
|| structId == MQ_STRUCTID_SPQI || structId == MQ_STRUCTID_SPQI_EBCDIC
|| structId == MQ_STRUCTID_SPPO || structId == MQ_STRUCTID_SPPO_EBCDIC
@@ -1372,12 +1582,12 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, (const char*)sStructId);
g_free(sStructId);
mq_tree = proto_item_add_subtree(ti, ett_mq_spi_base);
-
+
proto_tree_add_item(mq_tree, hf_mq_spi_base_structid, tvb, offset, 4, FALSE);
proto_tree_add_item(mq_tree, hf_mq_spi_base_version, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_spi_base_length, tvb, offset + 8, 4, bLittleEndian);
}
-
+
if (structId == MQ_STRUCTID_SPQO && tvb_length_remaining(tvb, offset) >= 16)
{
if (tree)
@@ -1385,7 +1595,7 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gint iVerbNumber = 0;
proto_tree_add_item(mq_tree, hf_mq_spi_spqo_nbverb, tvb, offset + 12, 4, bLittleEndian);
iVerbNumber = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
-
+
if (tvb_length_remaining(tvb, offset) >= iVerbNumber * 20 + 16)
{
gint iVerb = 0;
@@ -1432,11 +1642,11 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *mq_tree_sub = NULL;
gint iOptionsFlags;
-
+
ti = proto_tree_add_item(mq_tree, hf_mq_spi_spgo_options, tvb, offset + 12, 4, bLittleEndian);
mq_tree_sub = proto_item_add_subtree(ti, ett_mq_spi_options);
iOptionsFlags = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
-
+
proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_deferred, tvb, offset + 12, 4, iOptionsFlags);
proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_syncpoint, tvb, offset + 12, 4, iOptionsFlags);
proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_blank, tvb, offset + 12, 4, iOptionsFlags);
@@ -1455,437 +1665,499 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
}
- }
- else if ((structId == MQ_STRUCTID_ID || structId == MQ_STRUCTID_ID_EBCDIC) && tvb_length_remaining(tvb, offset) >= 44)
- {
- guint8 iVersionID = 0;
- gint iSizeID = 0;
- iVersionID = tvb_get_guint8(tvb, offset + 4);
- iSizeID = (iVersionID < 4 ? 44 : 104); /* guess */
- /* actually 102 but must be aligned to multiple of 4 */
-
- if (check_col(pinfo->cinfo, COL_INFO))
+ else if ((opcode >= 0xA0 && opcode <= 0xB9) && tvb_length_remaining(tvb, offset) >= 16)
{
- guint8* sChannel;
- sChannel = tvb_get_string(tvb, offset + 24, 20);
- if (strip_trailing_blanks(sChannel, 20) != 0)
+ /* The XA structures are special because they do not start with a structid */
+ if (tree)
{
- col_append_fstr(pinfo->cinfo, COL_INFO, ": CHL=%s", sChannel);
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, 16, "%s (%s)", MQ_TEXT_XA, val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
+ mq_tree = proto_item_add_subtree(ti, ett_mq_xa);
+
+ proto_tree_add_item(mq_tree, hf_mq_xa_length, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xa_returnvalue, tvb, offset + 4, 4, bLittleEndian);
+
+ /* Transaction Manager flags */
+ {
+ proto_tree *mq_tree_sub = NULL;
+ guint32 iTMFlags;
+
+ ti = proto_tree_add_item(mq_tree, hf_mq_xa_tmflags, tvb, offset + 8, 4, bLittleEndian);
+ mq_tree_sub = proto_item_add_subtree(ti, ett_mq_xa_tmflags);
+ iTMFlags = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
+
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_onephase, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_fail, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_resume, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_success, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_suspend, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_startrscan, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_endrscan, tvb, offset + 8, 4, iTMFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_join, tvb, offset + 8, 4, iTMFlags);
+ }
+
+ proto_tree_add_item(mq_tree, hf_mq_xa_rmid, tvb, offset + 12, 4, bLittleEndian);
}
- g_free(sChannel);
- }
-
- if (tree)
- {
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeID, MQ_TEXT_ID);
- mq_tree = proto_item_add_subtree(ti, ett_mq_id);
-
- proto_tree_add_item(mq_tree, hf_mq_id_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_id_level, tvb, offset + 4, 1, FALSE);
-
- /* ID flags */
+ offset += 16;
+ if (opcode == MQ_TST_XA_START || opcode == MQ_TST_XA_END || opcode == MQ_TST_XA_PREPARE
+ || opcode == MQ_TST_XA_COMMIT || opcode == MQ_TST_XA_ROLLBACK || opcode == MQ_TST_XA_FORGET
+ || opcode == MQ_TST_XA_COMPLETE)
{
- proto_tree *mq_tree_sub = NULL;
- guint8 iIDFlags;
-
- ti = proto_tree_add_item(mq_tree, hf_mq_id_flags, tvb, offset + 5, 1, FALSE);
- mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_icf);
- iIDFlags = tvb_get_guint8(tvb, offset + 5);
-
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_runtime, tvb, offset + 5, 1, iIDFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_svrsec, tvb, offset + 5, 1, iIDFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_mqreq, tvb, offset + 5, 1, iIDFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_splitmsg, tvb, offset + 5, 1, iIDFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_convcap, tvb, offset + 5, 1, iIDFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_msgseq, tvb, offset + 5, 1, iIDFlags);
+ gint iSizeXid = 0;
+ if ((iSizeXid = dissect_mq_xid(tvb, mqroot_tree, bLittleEndian, offset)) != 0)
+ offset += iSizeXid;
}
-
- proto_tree_add_item(mq_tree, hf_mq_id_unknown2, tvb, offset + 6, 1, FALSE);
-
- /* Error flags */
+ else if ((opcode == MQ_TST_XA_OPEN || opcode == MQ_TST_XA_CLOSE)
+ && tvb_length_remaining(tvb, offset) >= 1)
{
- proto_tree *mq_tree_sub = NULL;
- guint8 iErrorFlags;
-
- ti = proto_tree_add_item(mq_tree, hf_mq_id_ieflags, tvb, offset + 7, 1, FALSE);
- mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_ief);
- iErrorFlags = tvb_get_guint8(tvb, offset + 7);
-
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_hbint, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_seqwrap, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgpb, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgsz, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_fap, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxtrsz, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_enc, tvb, offset + 7, 1, iErrorFlags);
- proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_ccsid, tvb, offset + 7, 1, iErrorFlags);
- }
-
- proto_tree_add_item(mq_tree, hf_mq_id_unknown4, tvb, offset + 8, 2, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_id_maxmsgperbatch, tvb, offset + 10, 2, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_id_maxtransmissionsize, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_id_maxmsgsize, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_id_sequencewrapvalue, tvb, offset + 20, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_id_channel, tvb, offset + 24, 20, FALSE);
- }
-
- if (iSizeID == 104 && tvb_length_remaining(tvb, offset) >= 104)
- {
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- guint8* sQueueManager;
- sQueueManager = tvb_get_string(tvb, offset + 48, 48);
- if (strip_trailing_blanks(sQueueManager,48) != 0)
+ guint8 iXAInfoLength = 0;
+ iXAInfoLength = tvb_get_guint8(tvb, offset);
+ if (tvb_length_remaining(tvb, offset) >= iXAInfoLength + 1)
{
- col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iXAInfoLength + 1, MQ_TEXT_XINF);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_xa_info);
+
+ proto_tree_add_item(mq_tree, hf_mq_xa_xainfo_length, tvb, offset, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xa_xainfo_value, tvb, offset + 1, iXAInfoLength, FALSE);
+ }
}
- g_free(sQueueManager);
+ offset += 1 + iXAInfoLength;
}
-
- if (tree)
+ else if ((opcode == MQ_TST_XA_RECOVER || opcode == MQ_TST_XA_RECOVER_REPLY)
+ && tvb_length_remaining(tvb, offset) >= 4)
{
- proto_tree_add_item(mq_tree, hf_mq_id_capflags, tvb, offset + 44, 1, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_id_unknown5, tvb, offset + 45, 1, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_id_ccsid, tvb, offset + 46, 2, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_id_queuemanager, tvb, offset + 48, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_id_heartbeatinterval, tvb, offset + 96, 4, bLittleEndian);
+ gint iNbXid = 0;
+ iNbXid = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
+ if (tree)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_xa_count, tvb, offset, 4, bLittleEndian);
+ }
+ offset += 4;
+ if (opcode == MQ_TST_XA_RECOVER_REPLY)
+ {
+ gint iXid = 0;
+ for (iXid = 0; iXid < iNbXid; iXid++)
+ {
+ gint iSizeXid = 0;
+ if ((iSizeXid = dissect_mq_xid(tvb, mqroot_tree, bLittleEndian, offset)) != 0)
+ offset += iSizeXid;
+ else
+ break;
+ }
+ }
}
-
}
- offset += iSizeID;
- }
- else if ((structId == MQ_STRUCTID_UID || structId == MQ_STRUCTID_UID_EBCDIC) && tvb_length_remaining(tvb, offset) >= 28)
- {
- gint iSizeUID = 0;
- if (check_col(pinfo->cinfo, COL_INFO))
+ else if ((structId == MQ_STRUCTID_ID || structId == MQ_STRUCTID_ID_EBCDIC) && tvb_length_remaining(tvb, offset) >= 5)
{
- guint8* sUserId;
- sUserId = tvb_get_string(tvb, offset + 4, 12);
- if (strip_trailing_blanks(sUserId, 12) != 0)
+ guint8 iVersionID = 0;
+ gint iSizeID = 0;
+ iVersionID = tvb_get_guint8(tvb, offset + 4);
+ iSizeID = (iVersionID < 4 ? 44 : 104); /* guess */
+ /* actually 102 but must be aligned to multiple of 4 */
+
+ if (iSizeID != 0 && tvb_length_remaining(tvb, offset) >= iSizeID)
{
- col_append_fstr(pinfo->cinfo, COL_INFO, ": User=%s", sUserId);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ guint8* sChannel;
+ sChannel = tvb_get_string(tvb, offset + 24, 20);
+ if (strip_trailing_blanks(sChannel, 20) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": CHL=%s", sChannel);
+ }
+ g_free(sChannel);
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeID, MQ_TEXT_ID);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_id);
+
+ proto_tree_add_item(mq_tree, hf_mq_id_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_id_level, tvb, offset + 4, 1, FALSE);
+
+ /* ID flags */
+ {
+ proto_tree *mq_tree_sub = NULL;
+ guint8 iIDFlags;
+
+ ti = proto_tree_add_item(mq_tree, hf_mq_id_flags, tvb, offset + 5, 1, FALSE);
+ mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_icf);
+ iIDFlags = tvb_get_guint8(tvb, offset + 5);
+
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_runtime, tvb, offset + 5, 1, iIDFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_svrsec, tvb, offset + 5, 1, iIDFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_mqreq, tvb, offset + 5, 1, iIDFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_splitmsg, tvb, offset + 5, 1, iIDFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_convcap, tvb, offset + 5, 1, iIDFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_msgseq, tvb, offset + 5, 1, iIDFlags);
+ }
+
+ proto_tree_add_item(mq_tree, hf_mq_id_unknown2, tvb, offset + 6, 1, FALSE);
+
+ /* Error flags */
+ {
+ proto_tree *mq_tree_sub = NULL;
+ guint8 iErrorFlags;
+
+ ti = proto_tree_add_item(mq_tree, hf_mq_id_ieflags, tvb, offset + 7, 1, FALSE);
+ mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_ief);
+ iErrorFlags = tvb_get_guint8(tvb, offset + 7);
+
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_hbint, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_seqwrap, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgpb, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgsz, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_fap, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxtrsz, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_enc, tvb, offset + 7, 1, iErrorFlags);
+ proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_ccsid, tvb, offset + 7, 1, iErrorFlags);
+ }
+
+ proto_tree_add_item(mq_tree, hf_mq_id_unknown4, tvb, offset + 8, 2, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_id_maxmsgperbatch, tvb, offset + 10, 2, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_id_maxtransmissionsize, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_id_maxmsgsize, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_id_sequencewrapvalue, tvb, offset + 20, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_id_channel, tvb, offset + 24, 20, FALSE);
+ }
+
+ if (iVersionID >= 4)
+ {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ guint8* sQueueManager;
+ sQueueManager = tvb_get_string(tvb, offset + 48, 48);
+ if (strip_trailing_blanks(sQueueManager,48) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
+ }
+ g_free(sQueueManager);
+ }
+
+ if (tree)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_id_capflags, tvb, offset + 44, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_id_unknown5, tvb, offset + 45, 1, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_id_ccsid, tvb, offset + 46, 2, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_id_queuemanager, tvb, offset + 48, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_id_heartbeatinterval, tvb, offset + 96, 4, bLittleEndian);
+ }
+
+ }
+ offset += iSizeID;
}
- g_free(sUserId);
}
-
- /* iSizeUID = (iVersionID < 5 ? 28 : 132); guess */
- /* The iVersionID is available in the previous ID segment, we should keep a state *
- * Instead we rely on the segment length announced in the TSH */
- iSizeUID = iSegmentLength - iSizeTSH;
- if (iSizeUID != 28 && iSizeUID != 132) iSizeUID = 132;
-
- if (tree)
- {
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeUID, MQ_TEXT_UID);
- mq_tree = proto_item_add_subtree(ti, ett_mq_uid);
-
- proto_tree_add_item(mq_tree, hf_mq_uid_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_uid_userid, tvb, offset + 4, 12, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_uid_password, tvb, offset + 16, 12, FALSE);
- }
-
- if (tvb_length_remaining(tvb, offset) >= 132)
+ else if ((structId == MQ_STRUCTID_UID || structId == MQ_STRUCTID_UID_EBCDIC) && tvb_length_remaining(tvb, offset) > 0)
{
- if (tree)
+ gint iSizeUID = 0;
+ /* iSizeUID = (iVersionID < 5 ? 28 : 132); guess */
+ /* The iVersionID is available in the previous ID segment, we should keep a state *
+ * Instead we rely on the segment length announced in the TSH */
+ iSizeUID = iSegmentLength - iSizeTSH;
+ if (iSizeUID != 28 && iSizeUID != 132) iSizeUID = 0;
+
+ if (iSizeUID != 0 && tvb_length_remaining(tvb, offset) >= iSizeUID)
{
- proto_tree_add_item(mq_tree, hf_mq_uid_longuserid, tvb, offset + 28, 64, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_uid_securityid, tvb, offset + 92, 40, FALSE);
- }
- }
- offset += iSizeUID;
- }
- if ((structId == MQ_STRUCTID_OD || structId == MQ_STRUCTID_OD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 168)
- {
- guint32 iVersionOD = 0;
- gint iSizeOD = 0;
- gint iNbrRecords = 0;
- iVersionOD = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
- /* Compute length according to version */
- switch (iVersionOD)
- {
- case 1: iSizeOD = 168; break;
- case 2: iSizeOD = 200; break;
- case 3: iSizeOD = 336; break;
- }
- if (iSizeOD >= 172)
- iNbrRecords = tvb_get_guint32_endian(tvb, offset + 168, bLittleEndian);
-
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- guint8* sQueue;
- sQueue = tvb_get_string(tvb, offset + 12, 48);
- if (strip_trailing_blanks(sQueue,48) != 0)
- {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Obj=%s", sQueue);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ guint8* sUserId;
+ sUserId = tvb_get_string(tvb, offset + 4, 12);
+ if (strip_trailing_blanks(sUserId, 12) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": User=%s", sUserId);
+ }
+ g_free(sUserId);
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeUID, MQ_TEXT_UID);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_uid);
+
+ proto_tree_add_item(mq_tree, hf_mq_uid_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_uid_userid, tvb, offset + 4, 12, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_uid_password, tvb, offset + 16, 12, FALSE);
+ }
+
+ if (iSizeUID == 132)
+ {
+ if (tree)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_uid_longuserid, tvb, offset + 28, 64, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_uid_securityid, tvb, offset + 92, 40, FALSE);
+ }
+ }
+ offset += iSizeUID;
}
- g_free(sQueue);
}
-
- if (tree)
+ if ((structId == MQ_STRUCTID_OD || structId == MQ_STRUCTID_OD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeOD, MQ_TEXT_OD);
- mq_tree = proto_item_add_subtree(ti, ett_mq_od);
-
- proto_tree_add_item(mq_tree, hf_mq_od_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_objecttype, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_objectname, tvb, offset + 12, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_objectqmgrname, tvb, offset + 60, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_dynamicqname, tvb, offset + 108, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_alternateuserid, tvb, offset + 156, 12, FALSE);
-
- if (iSizeOD >= 200 && tvb_length_remaining(tvb, offset) >= 200)
+ /* The OD struct can be present in several messages at different levels */
+ gint iSizeOD = 0;
+ guint32 iVersionOD = 0;
+ iVersionOD = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
+ /* Compute length according to version */
+ switch (iVersionOD)
{
- proto_tree_add_item(mq_tree, hf_mq_od_recspresent, tvb, offset + 168, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_knowndestcount, tvb, offset + 172, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_unknowndestcount, tvb, offset + 176, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_invaliddestcount, tvb, offset + 180, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_objectrecoffset, tvb, offset + 184, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_responserecoffset, tvb, offset + 188, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_objectrecptr, tvb, offset + 192, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_od_responserecptr, tvb, offset + 196, 4, bLittleEndian);
+ case 1: iSizeOD = 168; break;
+ case 2: iSizeOD = 200; break;
+ case 3: iSizeOD = 336; break;
}
-
- if (iSizeOD >= 336 && tvb_length_remaining(tvb, offset) >= 336)
+
+ if (iSizeOD != 0 && tvb_length_remaining(tvb, offset) >= iSizeOD)
{
- proto_tree_add_item(mq_tree, hf_mq_od_alternatesecurityid, tvb, offset + 200, 40, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_resolvedqname, tvb, offset + 240, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_od_resolvedqmgrname, tvb, offset + 288, 48, FALSE);
+ gint iNbrRecords = 0;
+ if (iVersionOD >= 2)
+ iNbrRecords = tvb_get_guint32_endian(tvb, offset + 168, bLittleEndian);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ guint8* sQueue;
+ sQueue = tvb_get_string(tvb, offset + 12, 48);
+ if (strip_trailing_blanks(sQueue,48) != 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Obj=%s", sQueue);
+ }
+ g_free(sQueue);
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeOD, MQ_TEXT_OD);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_od);
+
+ proto_tree_add_item(mq_tree, hf_mq_od_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_objecttype, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_objectname, tvb, offset + 12, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_objectqmgrname, tvb, offset + 60, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_dynamicqname, tvb, offset + 108, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_alternateuserid, tvb, offset + 156, 12, FALSE);
+
+ if (iVersionOD >= 2)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_od_recspresent, tvb, offset + 168, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_knowndestcount, tvb, offset + 172, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_unknowndestcount, tvb, offset + 176, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_invaliddestcount, tvb, offset + 180, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_objectrecoffset, tvb, offset + 184, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_responserecoffset, tvb, offset + 188, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_objectrecptr, tvb, offset + 192, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_od_responserecptr, tvb, offset + 196, 4, bLittleEndian);
+ }
+
+ if (iVersionOD >= 3)
+ {
+ proto_tree_add_item(mq_tree, hf_mq_od_alternatesecurityid, tvb, offset + 200, 40, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_resolvedqname, tvb, offset + 240, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_od_resolvedqmgrname, tvb, offset + 288, 48, FALSE);
+ }
+
+ }
+ offset += iSizeOD;
+
+ if (iNbrRecords > 0)
+ {
+ gint iOffsetOR = 0;
+ gint iOffsetRR = 0;
+ gint iSizeORRR = 0;
+
+ iDistributionListSize = iNbrRecords;
+ iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 184, bLittleEndian);
+ iOffsetRR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 188, bLittleEndian);
+ if ((iSizeORRR = dissect_mq_or(tvb, mqroot_tree, offset, iNbrRecords, iOffsetOR)) != 0)
+ offset += iSizeORRR;
+ if ((iSizeORRR = dissect_mq_rr(tvb, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetRR)) != 0)
+ offset += iSizeORRR;
+ }
}
-
- }
- offset += iSizeOD;
-
- if (iNbrRecords > 0)
- {
- gint iOffsetOR = 0;
- gint iOffsetRR = 0;
- gint iSizeORRR = 0;
-
- iDistributionListSize = iNbrRecords;
- iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 184, bLittleEndian);
- iOffsetRR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 188, bLittleEndian);
- if ((iSizeORRR = dissect_mq_or(tvb, pinfo, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetOR)) != 0)
- offset += iSizeORRR;
- if ((iSizeORRR = dissect_mq_rr(tvb, pinfo, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetRR)) != 0)
- offset += iSizeORRR;
- }
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
- }
- if ((opcode == MQ_TST_MQOPEN || opcode == MQ_TST_MQCLOSE
- || opcode == MQ_TST_MQOPEN_REPLY || opcode == MQ_TST_MQCLOSE_REPLY)
- && tvb_length_remaining(tvb, offset) >= 4)
- {
- if (tree)
- {
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_OPEN);
- mq_tree = proto_item_add_subtree(ti, ett_mq_open);
- proto_tree_add_item(mq_tree, hf_mq_open_options, tvb, offset, 4, bLittleEndian);
- }
- offset += 4;
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
- }
- if ((iSizeMD = dissect_mq_md(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iOffsetFormat)) != 0)
- {
- gint iSizeGMO = 0;
- gint iSizePMO = 0;
- offset += iSizeMD;
-
- if ((iSizeGMO = dissect_mq_gmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset)) != 0)
- {
- offset += iSizeGMO;
- bPayload = TRUE;
- }
- else if ((iSizePMO = dissect_mq_pmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iDistributionListSize)) != 0)
- {
- offset += iSizePMO;
- bPayload = TRUE;
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- /* Now dissect the embedded structures */
- if (tvb_length_remaining(tvb, offset) >= 4)
+ if ((opcode == MQ_TST_MQOPEN || opcode == MQ_TST_MQCLOSE
+ || opcode == MQ_TST_MQOPEN_REPLY || opcode == MQ_TST_MQCLOSE_REPLY)
+ && tvb_length_remaining(tvb, offset) >= 4)
{
- if (bPayload == TRUE && tvb_length_remaining(tvb, offset) >= 4)
+ if (tree)
{
- iSizePayload = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
- if (tree)
- {
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_PUT);
- mq_tree = proto_item_add_subtree(ti, ett_mq_put);
- proto_tree_add_item(mq_tree, hf_mq_put_length, tvb, offset, 4, bLittleEndian);
- }
- offset += 4;
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_OPEN);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_open);
+ proto_tree_add_item(mq_tree, hf_mq_open_options, tvb, offset, 4, bLittleEndian);
}
+ offset += 4;
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- }
- if (iDistributionListSize > 0)
- {
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, " (Distribution List, Size=%d)", iDistributionListSize);
- }
- if (bPayload == TRUE)
- {
- if (iSizePayload != 0 && tvb_length_remaining(tvb, offset) > 0)
+ if ((iSizeMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
{
- /* For the following header structures, each structure has a "format" field
- which announces the type of the following structure. For dissection we
- do not use it and rely on the structid instead. */
- guint32 iHeadersLength = 0;
+ gint iSizeGMO = 0;
+ gint iSizePMO = 0;
+ offset += iSizeMD;
+
+ if ((iSizeGMO = dissect_mq_gmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset)) != 0)
+ {
+ offset += iSizeGMO;
+ bPayload = TRUE;
+ }
+ else if ((iSizePMO = dissect_mq_pmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iDistributionListSize)) != 0)
+ {
+ offset += iSizePMO;
+ bPayload = TRUE;
+ }
if (tvb_length_remaining(tvb, offset) >= 4)
{
- gint iSizeMD = 0;
- structId = tvb_get_ntohl(tvb, offset);
-
- if ((structId == MQ_STRUCTID_XQH || structId == MQ_STRUCTID_XQH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 104)
+ if (bPayload == TRUE)
{
- /* if MD.format == MQXMIT */
- gint iSizeXQH = 104;
+ iSizePayload = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
if (tree)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeXQH, MQ_TEXT_XQH);
- mq_tree = proto_item_add_subtree(ti, ett_mq_xqh);
-
- proto_tree_add_item(mq_tree, hf_mq_xqh_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_xqh_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_xqh_remoteq, tvb, offset + 8, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_xqh_remoteqmgr, tvb, offset + 56, 48, FALSE);
- }
- offset += iSizeXQH;
- iHeadersLength += iSizeXQH;
-
- if ((iSizeMD = dissect_mq_md(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iOffsetFormat)) != 0)
- {
- offset += iSizeMD;
- iHeadersLength += iSizeMD;
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_PUT);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_put);
+ proto_tree_add_item(mq_tree, hf_mq_put_length, tvb, offset, 4, bLittleEndian);
}
-
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
+ offset += 4;
}
- if ((structId == MQ_STRUCTID_DH || structId == MQ_STRUCTID_DH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 48)
+ }
+ }
+ if (iDistributionListSize > 0)
+ {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (Distribution List, Size=%d)", iDistributionListSize);
+ }
+ if (bPayload == TRUE)
+ {
+ if (iSizePayload != 0 && tvb_length_remaining(tvb, offset) > 0)
+ {
+ /* For the following header structures, each structure has a "format" field
+ which announces the type of the following structure. For dissection we
+ do not use it and rely on the structid instead. */
+ guint32 iHeadersLength = 0;
+ if (tvb_length_remaining(tvb, offset) >= 4)
{
- /* if MD.format == MQHDIST */
- gint iSizeDH = 48;
- gint iNbrRecords = 0;
- guint32 iRecFlags = 0;
-
- iNbrRecords = tvb_get_guint32_endian(tvb, offset + 36, bLittleEndian);
- iRecFlags = tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian);
- iOffsetFormat = offset + 20;
- if (tree)
+ gint iSizeMD = 0;
+ structId = tvb_get_ntohl(tvb, offset);
+
+ if ((structId == MQ_STRUCTID_XQH || structId == MQ_STRUCTID_XQH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 104)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDH, MQ_TEXT_DH);
- mq_tree = proto_item_add_subtree(ti, ett_mq_dh);
-
- proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecfields, tvb, offset + 32, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dh_recspresent, tvb, offset + 36, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dh_objectrecoffset , tvb, offset + 40, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecoffset, tvb, offset + 44, 4, bLittleEndian);
+ /* if MD.format == MQXMIT */
+ gint iSizeXQH = 104;
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeXQH, MQ_TEXT_XQH);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_xqh);
+
+ proto_tree_add_item(mq_tree, hf_mq_xqh_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xqh_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_xqh_remoteq, tvb, offset + 8, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_xqh_remoteqmgr, tvb, offset + 56, 48, FALSE);
+ }
+ offset += iSizeXQH;
+ iHeadersLength += iSizeXQH;
+
+ if ((iSizeMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
+ {
+ offset += iSizeMD;
+ iHeadersLength += iSizeMD;
+ }
+
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- offset += iSizeDH;
- iHeadersLength += iSizeDH;
-
- if (iNbrRecords > 0)
+ if ((structId == MQ_STRUCTID_DH || structId == MQ_STRUCTID_DH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 48)
{
- gint iOffsetOR = 0;
- gint iOffsetPMR = 0;
- gint iSizeORPMR = 0;
+ /* if MD.format == MQHDIST */
+ gint iSizeDH = 48;
+ gint iNbrRecords = 0;
+ guint32 iRecFlags = 0;
+
+ iNbrRecords = tvb_get_guint32_endian(tvb, offset + 36, bLittleEndian);
+ iRecFlags = tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian);
+ tMsgProps.iOffsetEncoding = offset + 12;
+ tMsgProps.iOffsetCcsid = offset + 16;
+ tMsgProps.iOffsetFormat = offset + 20;
- iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 40, bLittleEndian);
- iOffsetPMR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 44, bLittleEndian);
- if ((iSizeORPMR = dissect_mq_or(tvb, pinfo, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetOR)) != 0)
+ if (tree)
{
- offset += iSizeORPMR;
- iHeadersLength += iSizeORPMR;
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDH, MQ_TEXT_DH);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_dh);
+
+ proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecfields, tvb, offset + 32, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dh_recspresent, tvb, offset + 36, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dh_objectrecoffset , tvb, offset + 40, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecoffset, tvb, offset + 44, 4, bLittleEndian);
}
- if ((iSizeORPMR = dissect_mq_pmr(tvb, pinfo, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
+ offset += iSizeDH;
+ iHeadersLength += iSizeDH;
+
+ if (iNbrRecords > 0)
{
- offset += iSizeORPMR;
- iHeadersLength += iSizeORPMR;
+ gint iOffsetOR = 0;
+ gint iOffsetPMR = 0;
+ gint iSizeORPMR = 0;
+
+ iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 40, bLittleEndian);
+ iOffsetPMR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 44, bLittleEndian);
+ if ((iSizeORPMR = dissect_mq_or(tvb, mqroot_tree, offset, iNbrRecords, iOffsetOR)) != 0)
+ {
+ offset += iSizeORPMR;
+ iHeadersLength += iSizeORPMR;
+ }
+ if ((iSizeORPMR = dissect_mq_pmr(tvb, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
+ {
+ offset += iSizeORPMR;
+ iHeadersLength += iSizeORPMR;
+ }
}
+
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
-
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
- }
- if ((structId == MQ_STRUCTID_DLH || structId == MQ_STRUCTID_DLH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 172)
- {
- /* if MD.format == MQDEAD */
- gint iSizeDLH = 172;
- iOffsetFormat = offset + 116;
- if (tree)
+ if ((structId == MQ_STRUCTID_DLH || structId == MQ_STRUCTID_DLH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 172)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDLH, MQ_TEXT_DLH);
- mq_tree = proto_item_add_subtree(ti, ett_mq_dlh);
-
- proto_tree_add_item(mq_tree, hf_mq_dlh_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dlh_reason, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dlh_destq, tvb, offset + 12, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_destqmgr, tvb, offset + 60, 48, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_encoding, tvb, offset + 108, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dlh_ccsid, tvb, offset + 112, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dlh_format, tvb, offset + 116, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_putappltype, tvb, offset + 124, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_dlh_putapplname, tvb, offset + 128, 28, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_putdate, tvb, offset + 156, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_dlh_puttime, tvb, offset + 164, 8, FALSE);
+ /* if MD.format == MQDEAD */
+ gint iSizeDLH = 172;
+ tMsgProps.iOffsetEncoding = offset + 108;
+ tMsgProps.iOffsetCcsid = offset + 112;
+ tMsgProps.iOffsetFormat = offset + 116;
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDLH, MQ_TEXT_DLH);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_dlh);
+
+ proto_tree_add_item(mq_tree, hf_mq_dlh_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_reason, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_destq, tvb, offset + 12, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_destqmgr, tvb, offset + 60, 48, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_encoding, tvb, offset + 108, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_ccsid, tvb, offset + 112, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_format, tvb, offset + 116, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_putappltype, tvb, offset + 124, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_putapplname, tvb, offset + 128, 28, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_putdate, tvb, offset + 156, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_dlh_puttime, tvb, offset + 164, 8, FALSE);
+ }
+ offset += iSizeDLH;
+ iHeadersLength += iSizeDLH;
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- offset += iSizeDLH;
- iHeadersLength += iSizeDLH;
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
- }
- if ((structId == MQ_STRUCTID_MDE || structId == MQ_STRUCTID_MDE_EBCDIC) && tvb_length_remaining(tvb, offset) >= 72)
- {
- /* if MD.format == MQHMDE */
- gint iSizeMDE = 72;
- iOffsetFormat = offset + 20;
- if (tree)
+ if ((structId == MQ_STRUCTID_MDE || structId == MQ_STRUCTID_MDE_EBCDIC) && tvb_length_remaining(tvb, offset) >= 72)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMDE, MQ_TEXT_MDE);
- mq_tree = proto_item_add_subtree(ti, ett_mq_mde);
-
- proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 32, 24, FALSE);
- proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 56, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 60, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 64, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 68, 4, bLittleEndian);
- }
- offset += iSizeMDE;
- iHeadersLength += iSizeMDE;
- structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
- }
- if ((structId == MQ_STRUCTID_CIH || structId == MQ_STRUCTID_CIH_EBCDIC
- || structId == MQ_STRUCTID_IIH || structId == MQ_STRUCTID_IIH_EBCDIC
- || structId == MQ_STRUCTID_RFH || structId == MQ_STRUCTID_RFH_EBCDIC
- || structId == MQ_STRUCTID_RMH || structId == MQ_STRUCTID_RMH_EBCDIC
- || structId == MQ_STRUCTID_WIH || structId == MQ_STRUCTID_WIH_EBCDIC)
- && tvb_length_remaining(tvb, offset) >= 12)
- {
- /* Dissect the generic part of the other pre-defined headers */
- /* We assume that only one such header is present */
- gint iSizeHeader = 0;
- iSizeHeader = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
-
- if (tvb_length_remaining(tvb, offset) >= iSizeHeader)
- {
- iOffsetFormat = offset + 20;
- if (tree)
+ /* if MD.format == MQHMDE */
+ gint iSizeMDE = 72;
+ tMsgProps.iOffsetEncoding = offset + 12;
+ tMsgProps.iOffsetCcsid = offset + 16;
+ tMsgProps.iOffsetFormat = offset + 20;
+ if (tree)
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeHeader, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
- mq_tree = proto_item_add_subtree(ti, ett_mq_head);
-
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMDE, MQ_TEXT_MDE);
+ mq_tree = proto_item_add_subtree(ti, ett_mq_mde);
+
proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
@@ -1893,89 +2165,156 @@ dissect_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
- proto_tree_add_item(mq_tree, hf_mq_head_struct, tvb, offset + 32, iSizeHeader - 32, bLittleEndian);
-
+ proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 32, 24, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 56, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 60, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 64, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 68, 4, bLittleEndian);
}
- offset += iSizeHeader;
- iHeadersLength += iSizeHeader;
+ offset += iSizeMDE;
+ iHeadersLength += iSizeMDE;
structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
}
- }
- }
-
- if (iOffsetFormat != 0)
- {
- guint8* sFormat = NULL;
- sFormat = tvb_get_string(tvb, iOffsetFormat, 8);
- if (strip_trailing_blanks(sFormat, 8) == 0) sFormat = (guint8*)"MQNONE";
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Fmt=%s", sFormat);
- }
- if (tree)
+ if ((structId == MQ_STRUCTID_CIH || structId == MQ_STRUCTID_CIH_EBCDIC
+ || structId == MQ_STRUCTID_IIH || structId == MQ_STRUCTID_IIH_EBCDIC
+ || structId == MQ_STRUCTID_RFH || structId == MQ_STRUCTID_RFH_EBCDIC
+ || structId == MQ_STRUCTID_RMH || structId == MQ_STRUCTID_RMH_EBCDIC
+ || structId == MQ_STRUCTID_WIH || structId == MQ_STRUCTID_WIH_EBCDIC)
+ && tvb_length_remaining(tvb, offset) >= 12)
{
- proto_tree_add_string_hidden(tree, hf_mq_md_hidden_lastformat, tvb, iOffsetFormat, 8, (const char*)sFormat);
+ /* Dissect the generic part of the other pre-defined headers */
+ /* We assume that only one such header is present */
+ gint iSizeHeader = 0;
+ iSizeHeader = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
+
+ if (tvb_length_remaining(tvb, offset) >= iSizeHeader)
+ {
+ tMsgProps.iOffsetEncoding = offset + 12;
+ tMsgProps.iOffsetCcsid = offset + 16;
+ tMsgProps.iOffsetFormat = offset + 20;
+ if (tree)
+ {
+ ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeHeader, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
+ mq_tree = proto_item_add_subtree(ti, ett_mq_head);
+
+ proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
+ proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
+ proto_tree_add_item(mq_tree, hf_mq_head_struct, tvb, offset + 32, iSizeHeader - 32, bLittleEndian);
+
+ }
+ offset += iSizeHeader;
+ iHeadersLength += iSizeHeader;
+ structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
+ }
}
- g_free(sFormat);
- }
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_append_fstr(pinfo->cinfo, COL_INFO, " (%d bytes)", iSizePayload - iHeadersLength);
+ }
+
+ if (tMsgProps.iOffsetFormat != 0)
+ {
+ guint8* sFormat = NULL;
+ sFormat = tvb_get_string(tvb, tMsgProps.iOffsetFormat, 8);
+ if (strip_trailing_blanks(sFormat, 8) == 0) sFormat = (guint8*)"MQNONE";
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Fmt=%s", sFormat);
+ }
+ if (tree)
+ {
+ proto_tree_add_string_hidden(tree, hf_mq_md_hidden_lastformat, tvb, tMsgProps.iOffsetFormat, 8, (const char*)sFormat);
+ }
+ g_free(sFormat);
+ }
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (%d bytes)", iSizePayload - iHeadersLength);
+ }
+
+ {
+ /* Call subdissector for the payload */
+ tvbuff_t* next_tvb = NULL;
+ struct mqinfo mqinfo;
+ mqinfo.encoding = tvb_get_guint32_endian(tvb, tMsgProps.iOffsetEncoding, bLittleEndian);
+ mqinfo.ccsid = tvb_get_guint32_endian(tvb, tMsgProps.iOffsetCcsid, bLittleEndian);
+ tvb_memcpy(tvb, mqinfo.format, tMsgProps.iOffsetFormat, 8);
+ pinfo->private_data = &mqinfo;
+ next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ if (!dissector_try_heuristic(mq_heur_subdissector_list, next_tvb, pinfo, tree))
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
}
-
- /* At this point we could call another dissector, but the MQ middleware
- does not really have a standard out-of-band information like the TCP port
- which is centrally registered and that allows to know which format
- the application messages are. (P.S. : what about the the md.format ?)
- */
-
+ offset = tvb_length(tvb);
+ }
+ /* After all recognised structures have been dissected, process remaining structure*/
+ if (tvb_length_remaining(tvb, offset) >= 4)
+ {
+ structId = tvb_get_ntohl(tvb, offset);
if (tree)
{
- /* Add a tree for the payload */
- call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
+ proto_tree_add_text(mqroot_tree, tvb, offset, -1, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
}
}
- offset = tvb_length(tvb);
}
- }
- /* After all recognised structures have been dissected, process remaining structure*/
- if (tvb_length_remaining(tvb, offset) >= 4)
- {
- structId = tvb_get_ntohl(tvb, offset);
- if (tree)
+ else
{
- ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
+ /* This is a MQ segment continuation (no PDU reassembly is done) */
+ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " [Segment Continuation]");
+ call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
}
}
}
else
{
- /* This packet is a continuation of a segment */
- if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
+ /* This packet is a TCP continuation of a segment (if desegmentation is not enabled) */
+ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "Continuation");
if (tree)
{
- ti = proto_tree_add_item(tree, proto_mq, tvb, offset, -1, FALSE);
- call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
+ proto_tree_add_item(tree, proto_mq, tvb, offset, -1, FALSE);
}
+ call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
}
}
}
+static guint
+get_mq_pdu_len(tvbuff_t *tvb, int offset)
+{
+ if (tvb_length_remaining(tvb, offset) >= 8)
+ {
+ if ((tvb_get_ntohl(tvb, 0) == MQ_STRUCTID_TSH || tvb_get_ntohl(tvb, 0) == MQ_STRUCTID_TSH_EBCDIC))
+ return tvb_get_ntohl(tvb, offset + 4);
+ }
+ return 0;
+}
+
+static void
+dissect_mq_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ tcp_dissect_pdus(tvb, pinfo, tree, mq_desegment, 28, get_mq_pdu_len, dissect_mq_pdu);
+}
+
+static void
+dissect_mq_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_mq_pdu(tvb, pinfo, tree);
+}
+
static gboolean
-dissect_mq_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_mq_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint iProto)
{
if (tvb_length(tvb) >= 28)
{
guint32 structId;
- guint32 iLength;
guint8 cEndian;
structId = tvb_get_ntohl(tvb, 0);
- iLength = tvb_get_ntohl(tvb, 4);
cEndian = tvb_get_guint8(tvb, 8);
if ((structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC)
- && (cEndian == MQ_LITTLE_ENDIAN || cEndian == MQ_BIG_ENDIAN)
- && (iLength == tvb_length(tvb)))
+ && (cEndian == MQ_LITTLE_ENDIAN || cEndian == MQ_BIG_ENDIAN))
{
/* Register this dissector for this conversation */
conversation_t *conversation = NULL;
@@ -1984,16 +2323,34 @@ dissect_mq_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
}
- conversation_set_dissector(conversation, mq_handle);
+ if (iProto == MQ_XPT_TCP) conversation_set_dissector(conversation, mq_tcp_handle);
/* Dissect the packet */
- dissect_mq(tvb, pinfo, tree);
+ dissect_mq_pdu(tvb, pinfo, tree);
return TRUE;
}
}
return FALSE;
}
+static gboolean
+dissect_mq_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_TCP);
+}
+
+static gboolean
+dissect_mq_heur_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_NETBIOS);
+}
+
+static gboolean
+dissect_mq_heur_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_HTTP);
+}
+
void
proto_register_mq(void)
{
@@ -2025,23 +2382,20 @@ proto_register_mq(void)
{ &hf_mq_tsh_ccsid,
{ "Character set", "mq.tsh.ccsid", FT_UINT16, BASE_DEC, NULL, 0x0, "TSH CCSID", HFILL }},
- { &hf_mq_tsh_unknown4,
- { "Unknown4", "mq.tsh.unknown4", FT_UINT16, BASE_HEX, NULL, 0x0, "TSH Unknown4", HFILL }},
-
- { &hf_mq_tsh_length,
- { "Length", "mq.tsh.length", FT_UINT32, BASE_DEC, NULL, 0x0, "TSH Length", HFILL }},
+ { &hf_mq_tsh_padding,
+ { "Padding", "mq.tsh.padding", FT_UINT16, BASE_HEX, NULL, 0x0, "TSH Padding", HFILL }},
- { &hf_mq_tsh_completioncode,
- { "Completion code", "mq.tsh.completioncode", FT_UINT32, BASE_DEC, NULL, 0x0, "TSH Completion code", HFILL }},
+ { &hf_mq_api_replylength,
+ { "Reply length", "mq.tsh.replylength", FT_UINT32, BASE_DEC, NULL, 0x0, "API Reply length", HFILL }},
- { &hf_mq_tsh_reasoncode,
- { "Reason code", "mq.tsh.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "TSH Reason code", HFILL }},
+ { &hf_mq_api_completioncode,
+ { "Completion code", "mq.tsh.completioncode", FT_UINT32, BASE_DEC, NULL, 0x0, "API Completion code", HFILL }},
- { &hf_mq_tsh_statuscode,
- { "Status code", "mq.tsh.statuscode", FT_UINT32, BASE_DEC, VALS(mq_status_vals), 0x0, "TSH Status code", HFILL }},
+ { &hf_mq_api_reasoncode,
+ { "Reason code", "mq.tsh.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "API Reason code", HFILL }},
- { &hf_mq_tsh_queuehandle,
- { "Queue handle", "mq.tsh.queuehandle", FT_UINT32, BASE_HEX, NULL, 0x0, "TSH Queue handle", HFILL }},
+ { &hf_mq_api_objecthandle,
+ { "Object handle", "mq.tsh.hobj", FT_UINT32, BASE_HEX, NULL, 0x0, "API Object handle", HFILL }},
{ &hf_mq_tsh_tcf_confirmreq,
{ "Confirm request", "mq.tsh.tcf.confirmreq", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_CONFIRM_REQUEST, "TSH TCF Confirm request", HFILL }},
@@ -2152,7 +2506,7 @@ proto_register_mq(void)
{ "Unknown5", "mq.id.unknown5", FT_UINT8, BASE_HEX, NULL, 0x0, "ID unknown5", HFILL }},
{ &hf_mq_id_ccsid,
- { "Character set", "mq.id.ccsid", FT_UINT16, BASE_DEC, NULL, 0x0, "ID unknown5", HFILL }},
+ { "Character set", "mq.id.ccsid", FT_UINT16, BASE_DEC, NULL, 0x0, "ID character set", HFILL }},
{ &hf_mq_id_queuemanager,
{ "Queue manager", "mq.id.qm", FT_STRINGZ, BASE_HEX, NULL, 0x0, "ID Queue manager", HFILL }},
@@ -2209,7 +2563,7 @@ proto_register_mq(void)
{ "Application name", "mq.conn.appname", FT_STRINGZ, BASE_HEX, NULL, 0x0, "CONN application name", HFILL }},
{ &hf_mq_conn_apptype,
- { "Application type", "mq.conn.apptype", FT_UINT32, BASE_DEC, NULL, 0x0, "CONN application type", HFILL }},
+ { "Application type", "mq.conn.apptype", FT_INT32, BASE_DEC, NULL, 0x0, "CONN application type", HFILL }},
{ &hf_mq_conn_acttoken,
{ "Accounting token", "mq.conn.acttoken", FT_BYTES, BASE_HEX, NULL, 0x0, "CONN accounting token", HFILL }},
@@ -2316,9 +2670,18 @@ proto_register_mq(void)
{ &hf_mq_open_options,
{ "Options", "mq.open.options", FT_UINT32, BASE_DEC, NULL, 0x0, "OPEN options", HFILL }},
+ { &hf_mq_ping_length,
+ { "Length", "mq.ping.length", FT_UINT32, BASE_DEC, NULL, 0x0, "PING length", HFILL }},
+
{ &hf_mq_ping_buffer,
{ "Buffer", "mq.ping.buffer", FT_BYTES, BASE_DEC, NULL, 0x0, "PING buffer", HFILL }},
+ { &hf_mq_status_length,
+ { "Length", "mq.status.length", FT_UINT32, BASE_DEC, NULL, 0x0, "STATUS length", HFILL }},
+
+ { &hf_mq_status_code,
+ { "Code", "mq.status.code", FT_UINT32, BASE_DEC, VALS(mq_status_vals), 0x0, "STATUS code", HFILL }},
+
{ &hf_mq_od_structid,
{ "OD structid", "mq.od.structid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OD structid", HFILL }},
@@ -2413,7 +2776,7 @@ proto_register_mq(void)
{ "Message type", "mq.md.msgtype", FT_UINT32, BASE_DEC, NULL, 0x0, "MD message type", HFILL }},
{ &hf_mq_md_expiry,
- { "Expiry", "mq.md.expiry", FT_UINT32, BASE_DEC, NULL, 0x0, "MD expiry", HFILL }},
+ { "Expiry", "mq.md.expiry", FT_INT32, BASE_DEC, NULL, 0x0, "MD expiry", HFILL }},
{ &hf_mq_md_feedback,
{ "Feedback", "mq.md.feedback", FT_UINT32, BASE_DEC, NULL, 0x0, "MD feedback", HFILL }},
@@ -2422,13 +2785,13 @@ proto_register_mq(void)
{ "Encoding", "mq.md.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "MD encoding", HFILL }},
{ &hf_mq_md_ccsid,
- { "Character set", "mq.md.ccsid", FT_UINT32, BASE_DEC, NULL, 0x0, "MD character set", HFILL }},
+ { "Character set", "mq.md.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "MD character set", HFILL }},
{ &hf_mq_md_format,
{ "Format", "mq.md.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD format", HFILL }},
{ &hf_mq_md_priority,
- { "Priority", "mq.md.priority", FT_UINT32, BASE_DEC, NULL, 0x0, "MD priority", HFILL }},
+ { "Priority", "mq.md.priority", FT_INT32, BASE_DEC, NULL, 0x0, "MD priority", HFILL }},
{ &hf_mq_md_persistence,
{ "Persistence", "mq.md.persistence", FT_UINT32, BASE_DEC, NULL, 0x0, "MD persistence", HFILL }},
@@ -2458,7 +2821,7 @@ proto_register_mq(void)
{ "ApplicationId data", "mq.md.appldata", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put applicationId data", HFILL }},
{ &hf_mq_md_putappltype,
- { "Put Application Type", "mq.md.appltype", FT_UINT32, BASE_DEC, NULL, 0x0, "MD Put application type", HFILL }},
+ { "Put Application Type", "mq.md.appltype", FT_INT32, BASE_DEC, NULL, 0x0, "MD Put application type", HFILL }},
{ &hf_mq_md_putapplname,
{ "Put Application Name", "mq.md.applname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put application name", HFILL }},
@@ -2485,7 +2848,7 @@ proto_register_mq(void)
{ "Message flags", "mq.md.msgflags", FT_UINT32, BASE_HEX, NULL, 0x0, "MD Message flags", HFILL }},
{ &hf_mq_md_originallength,
- { "Original length", "mq.md.origdata", FT_UINT32, BASE_DEC, NULL, 0x0, "MD Original length", HFILL }},
+ { "Original length", "mq.md.origdata", FT_INT32, BASE_DEC, NULL, 0x0, "MD Original length", HFILL }},
{ &hf_mq_md_hidden_lastformat,
{ "Last format", "mq.md.lastformat", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Last format", HFILL }},
@@ -2509,13 +2872,13 @@ proto_register_mq(void)
{ "Encoding", "mq.dlh.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH encoding", HFILL }},
{ &hf_mq_dlh_ccsid,
- { "Character set", "mq.dlh.ccsid", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH character set", HFILL }},
+ { "Character set", "mq.dlh.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "DLH character set", HFILL }},
{ &hf_mq_dlh_format,
{ "Format", "mq.dlh.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH format", HFILL }},
{ &hf_mq_dlh_putappltype,
- { "Put application type", "mq.dlh.putappltype", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH put application type", HFILL }},
+ { "Put application type", "mq.dlh.putappltype", FT_INT32, BASE_DEC, NULL, 0x0, "DLH put application type", HFILL }},
{ &hf_mq_dlh_putapplname,
{ "Put application name", "mq.dlh.putapplname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH put application name", HFILL }},
@@ -2548,7 +2911,7 @@ proto_register_mq(void)
{ "Options", "mq.gmo.options", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO options", HFILL }},
{ &hf_mq_gmo_waitinterval,
- { "Wait Interval", "mq.gmo.waitint", FT_UINT32, BASE_DEC, NULL, 0x0, "GMO wait interval", HFILL }},
+ { "Wait Interval", "mq.gmo.waitint", FT_INT32, BASE_DEC, NULL, 0x0, "GMO wait interval", HFILL }},
{ &hf_mq_gmo_signal1,
{ "Signal 1", "mq.gmo.signal1", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO signal 1", HFILL }},
@@ -2578,7 +2941,7 @@ proto_register_mq(void)
{ "Message token", "mq.gmo.msgtoken", FT_BYTES, BASE_HEX, NULL, 0x0, "GMO message token", HFILL }},
{ &hf_mq_gmo_returnedlength,
- { "Returned length", "mq.gmo.retlen", FT_UINT32, BASE_DEC, NULL, 0x0, "GMO returned length", HFILL }},
+ { "Returned length", "mq.gmo.retlen", FT_INT32, BASE_DEC, NULL, 0x0, "GMO returned length", HFILL }},
{ &hf_mq_pmo_structid,
{ "PMO structid", "mq.pmo.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "PMO structid", HFILL }},
@@ -2590,7 +2953,7 @@ proto_register_mq(void)
{ "Options", "mq.pmo.options", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO options", HFILL }},
{ &hf_mq_pmo_timeout,
- { "Timeout", "mq.pmo.timeout", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO time out", HFILL }},
+ { "Timeout", "mq.pmo.timeout", FT_INT32, BASE_DEC, NULL, 0x0, "PMO time out", HFILL }},
{ &hf_mq_pmo_context,
{ "Context", "mq.pmo.context", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO context", HFILL }},
@@ -2641,7 +3004,7 @@ proto_register_mq(void)
{ "Encoding", "mq.head.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "Header encoding", HFILL }},
{ &hf_mq_head_ccsid,
- { "Character set", "mq.head.ccsid", FT_UINT32, BASE_DEC, NULL, 0x0, "Header character set", HFILL }},
+ { "Character set", "mq.head.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "Header character set", HFILL }},
{ &hf_mq_head_format,
{ "Format", "mq.head.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "Header format", HFILL }},
@@ -2650,13 +3013,74 @@ proto_register_mq(void)
{ "Flags", "mq.head.flags", FT_UINT32, BASE_DEC, NULL, 0x0, "Header flags", HFILL }},
{ &hf_mq_head_struct,
- { "Struct", "mq.head.struct", FT_BYTES, BASE_HEX, NULL, 0x0, "Header struct", HFILL }}
+ { "Struct", "mq.head.struct", FT_BYTES, BASE_HEX, NULL, 0x0, "Header struct", HFILL }},
+
+ { &hf_mq_xa_length,
+ { "Length", "mq.xa.length", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Length", HFILL }},
+
+ { &hf_mq_xa_returnvalue,
+ { "Return value", "mq.xa.returnvalue", FT_INT32, BASE_DEC, VALS(mq_xaer_vals), 0x0, "XA Return Value", HFILL }},
+
+ { &hf_mq_xa_tmflags,
+ { "Transaction Manager Flags", "mq.xa.tmflags", FT_UINT32, BASE_HEX, NULL, 0x0, "XA Transaction Manager Flags", HFILL }},
+
+ { &hf_mq_xa_rmid,
+ { "Resource manager ID", "mq.xa.rmid", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Resource Manager ID", HFILL }},
+
+ { &hf_mq_xa_count,
+ { "Number of Xid", "mq.xa.nbxid", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Number of Xid", HFILL }},
+
+ { &hf_mq_xa_tmflags_join,
+ { "JOIN", "mq.xa.tmflags.join", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMJOIN, "XA TM Flags JOIN", HFILL }},
+
+ { &hf_mq_xa_tmflags_endrscan,
+ { "ENDRSCAN", "mq.xa.tmflags.endrscan", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMENDRSCAN, "XA TM Flags ENDRSCAN", HFILL }},
+
+ { &hf_mq_xa_tmflags_startrscan,
+ { "STARTRSCAN", "mq.xa.tmflags.startrscan", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSTARTRSCAN, "XA TM Flags STARTRSCAN", HFILL }},
+
+ { &hf_mq_xa_tmflags_suspend,
+ { "SUSPEND", "mq.xa.tmflags.suspend", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSUSPEND, "XA TM Flags SUSPEND", HFILL }},
+
+ { &hf_mq_xa_tmflags_success,
+ { "SUCCESS", "mq.xa.tmflags.success", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSUCCESS, "XA TM Flags SUCCESS", HFILL }},
+
+ { &hf_mq_xa_tmflags_resume,
+ { "RESUME", "mq.xa.tmflags.resume", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMRESUME, "XA TM Flags RESUME", HFILL }},
+
+ { &hf_mq_xa_tmflags_fail,
+ { "FAIL", "mq.xa.tmflags.fail", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMFAIL, "XA TM Flags FAIL", HFILL }},
+
+ { &hf_mq_xa_tmflags_onephase,
+ { "ONEPHASE", "mq.xa.tmflags.onephase", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMONEPHASE, "XA TM Flags ONEPHASE", HFILL }},
+
+ { &hf_mq_xa_xid_formatid,
+ { "Format ID", "mq.xa.xid.formatid", FT_INT32, BASE_DEC, NULL, 0x0, "XA Xid Format ID", HFILL }},
+
+ { &hf_mq_xa_xid_globalxid_length,
+ { "Global TransactionId Length", "mq.xa.xid.gxidl", FT_UINT8, BASE_DEC, NULL, 0x0, "XA Xid Global TransactionId Length", HFILL }},
+
+ { &hf_mq_xa_xid_brq_length,
+ { "Branch Qualifier Length", "mq.xa.xid.bql", FT_UINT8, BASE_DEC, NULL, 0x0, "XA Xid Branch Qualifier Length", HFILL }},
+
+ { &hf_mq_xa_xid_globalxid,
+ { "Global TransactionId", "mq.xa.xid.gxid", FT_BYTES, BASE_DEC, NULL, 0x0, "XA Xid Global TransactionId", HFILL }},
+
+ { &hf_mq_xa_xid_brq,
+ { "Branch Qualifier", "mq.xa.xid.bq", FT_BYTES, BASE_DEC, NULL, 0x0, "XA Xid Branch Qualifier", HFILL }},
+
+ { &hf_mq_xa_xainfo_length,
+ { "Length", "mq.xa.xainfo.length", FT_UINT8, BASE_DEC, NULL, 0x0, "XA XA_info Length", HFILL }},
+
+ { &hf_mq_xa_xainfo_value,
+ { "Value", "mq.xa.xainfo.value", FT_STRINGZ, BASE_DEC, NULL, 0x0, "XA XA_info Value", HFILL }}
};
static gint *ett[] = {
&ett_mq,
&ett_mq_tsh,
&ett_mq_tsh_tcf,
+ &ett_mq_api,
&ett_mq_msh,
&ett_mq_xqh,
&ett_mq_id,
@@ -2671,6 +3095,7 @@ proto_register_mq(void)
&ett_mq_put,
&ett_mq_open,
&ett_mq_ping,
+ &ett_mq_status,
&ett_mq_od,
&ett_mq_or,
&ett_mq_rr,
@@ -2682,14 +3107,25 @@ proto_register_mq(void)
&ett_mq_gmo,
&ett_mq_pmo,
&ett_mq_head,
+ &ett_mq_xa,
+ &ett_mq_xa_tmflags,
+ &ett_mq_xa_xid,
+ &ett_mq_xa_info,
};
+ module_t *mq_module;
+
proto_mq = proto_register_protocol("WebSphere MQ", "MQ", "mq");
proto_register_field_array(proto_mq, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
- mq_handle = create_dissector_handle(dissect_mq, proto_mq);
+ register_heur_dissector_list("mq", &mq_heur_subdissector_list);
+ mq_module = prefs_register_protocol(proto_mq, NULL);
+ prefs_register_bool_preference(mq_module, "reassembly", /*"desegment",*/
+ "Desegment all MQ messages spanning multiple TCP segments",
+ "Whether the MQ dissector should desegment all messages spanning multiple TCP segments",
+ &mq_desegment);
}
void
@@ -2699,8 +3135,14 @@ proto_reg_handoff_mq(void)
* class of applications (web browser, e-mail client, ...) and have a very well
* known port number, the MQ applications are most often specific to a business application */
- dissector_add_handle("tcp.port", mq_handle);
- heur_dissector_add("tcp", dissect_mq_heur, proto_mq);
+ mq_tcp_handle = create_dissector_handle(dissect_mq_tcp, proto_mq);
+ mq_spx_handle = create_dissector_handle(dissect_mq_spx, proto_mq);
+
+ dissector_add_handle("tcp.port", mq_tcp_handle);
+ heur_dissector_add("tcp", dissect_mq_heur_tcp, proto_mq);
+ heur_dissector_add("netbios", dissect_mq_heur_netbios, proto_mq);
+ heur_dissector_add("http", dissect_mq_heur_http, proto_mq);
+ dissector_add("spx.socket", MQ_SOCKET_SPX, mq_spx_handle);
data_handle = find_dissector("data");
}
diff --git a/packet-mq.h b/packet-mq.h
new file mode 100644
index 0000000000..137527b52a
--- /dev/null
+++ b/packet-mq.h
@@ -0,0 +1,36 @@
+/* packet-mq.h
+ *
+ * $Id: packet-mq.h,v 1.1 2004/05/01 21:18:10 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.
+ */
+
+#ifndef __PACKET_MQ_H__
+#define __PACKET_MQ_H__
+
+/*
+ * Private data passed from the MQ dissector to subdissectors.
+ */
+struct mqinfo {
+ guint32 encoding; /* Message encoding */
+ guint32 ccsid; /* Message character set */
+ guint8 format[8]; /* Message format */
+};
+
+#endif