change the signature that asn2wrs generates for functions to marm all parameters...
[obnox/wireshark/wip.git] / epan / dissectors / packet-mq.c
1 /* packet-mq.c
2  * Routines for IBM WebSphere MQ packet dissection
3  *
4  * metatech <metatech@flashmail.com>
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*  WebSphere MQ in a nutshell
28 *
29 *   IBM WebSphere MQ (formerly IBM MQSeries) is an asynchronous proprietary messaging middleware that is based on message queues.
30 *   MQ can run on more than 35 platforms, amongst which UNIX, Windows and mainframes.
31 *   MQ can be transported on top of TCP, UDP, HTTP, NetBIOS, SPX, SNA LU 6.2, DECnet.
32 *   MQ has language bindings for C, C++, Java, .NET, COBOL, PL/I, OS/390 assembler, TAL, Visual Basic.
33 *
34 *   The basic MQ topology is on one side the queue manager which hosts the queues.  On the other side the
35 *   applications connect to the queue manager, open a queue, and put or get messages to/from that queue.
36 *
37 *       The MQ middleware allows very generic operations (send, receive) and can be compared to the
38 *   socket API in terms of genericity, but it is more abstract and offers higher-level functionalities
39 *   (eg transactions, ...)
40 *
41 *   The MQ middleware is not really intended to be run over public networks between parties
42 *   that do not know each other in advance, but is rather used on private corporate networks
43 *   between business applications (it can be compared to a database server for that aspect).
44 *
45 *   The wire format of an MQ segment is a sequence of structures.  Most structures start with a 4-letter struct identifier.
46 *   MQ is a fixed-sized format, most fields have maximum lengths defined in the MQ API.
47 *   MQ is popular on mainframes because it was available before TCP/IP.
48 *   MQ supports both ASCII-based and EBCDIC-based character sets.
49 *
50 *   MQ API documentation is called "WebSphere MQ Application Programming Reference"
51 *
52 *   Possible structures combinations :
53 *       TSH [ ID ^ UID ^ CONN ^ INQ ^ OD ]
54 *   TSH MSH XQH MD [ PAYLOAD ]
55 *   TSH [OD] MD [ GMO ^ PMO ] [ [XQH MD] PAYLOAD ]
56 *   TSH [ SPQU ^ SPPU ^ SPGU ^ SPAU [ SPQI ^ SPQO ^ SPPI ^ SPPO ^ SPGI ^ SPGO ^ SPAI ^ SPAO]]
57 *   TSH [ XA ] [ XINFO | XID ]
58 *   where PAYLOAD = [ DH ] [ DLH ] [ MDE ] BUFF
59 *
60 *   This dissector is a beta version.  To be improved
61 *   - Translate the integers/flags into their descriptions
62 *   - Find the semantics of the unknown fields
63 *   - Display EBCDIC strings as ASCII
64 *   - Packets which structures built on different platforms
65 */
66
67 #ifdef HAVE_CONFIG_H
68 # include "config.h"
69 #endif
70
71 #include <glib.h>
72 #include <epan/packet.h>
73 #include <epan/emem.h>
74 #include <epan/conversation.h>
75 #include <epan/reassemble.h>
76 #include <epan/prefs.h>
77 #include "packet-tcp.h"
78 #include "packet-mq.h"
79
80 static int proto_mq = -1;
81 static int hf_mq_tsh_structid = -1;
82 static int hf_mq_tsh_packetlength = -1;
83 static int hf_mq_tsh_byteorder = -1;
84 static int hf_mq_tsh_opcode = -1;
85 static int hf_mq_tsh_controlflags = -1;
86 static int hf_mq_tsh_reserved = -1;
87 static int hf_mq_tsh_luwid = -1;
88 static int hf_mq_tsh_encoding = -1;
89 static int hf_mq_tsh_ccsid = -1;
90 static int hf_mq_tsh_padding = -1;
91 static int hf_mq_tsh_tcf_confirmreq = -1;
92 static int hf_mq_tsh_tcf_error = -1;
93 static int hf_mq_tsh_tcf_reqclose = -1;
94 static int hf_mq_tsh_tcf_closechann = -1;
95 static int hf_mq_tsh_tcf_first = -1;
96 static int hf_mq_tsh_tcf_last = -1;
97 static int hf_mq_tsh_tcf_reqacc = -1;
98 static int hf_mq_tsh_tcf_dlq = -1;
99 static int hf_mq_api_replylength = -1;
100 static int hf_mq_api_completioncode = -1;
101 static int hf_mq_api_reasoncode = -1;
102 static int hf_mq_api_objecthandle = -1;
103 static int hf_mq_msh_structid = -1;
104 static int hf_mq_msh_seqnum = -1;
105 static int hf_mq_msh_datalength = -1;
106 static int hf_mq_msh_unknown1 = -1;
107 static int hf_mq_msh_msglength = -1;
108 static int hf_mq_xqh_structid = -1;
109 static int hf_mq_xqh_version = -1;
110 static int hf_mq_xqh_remoteq = -1;
111 static int hf_mq_xqh_remoteqmgr = -1;
112 static int hf_mq_id_structid = -1;
113 static int hf_mq_id_level = -1;
114 static int hf_mq_id_flags = -1;
115 static int hf_mq_id_unknown2 = -1;
116 static int hf_mq_id_ieflags = -1;
117 static int hf_mq_id_unknown4 = -1;
118 static int hf_mq_id_maxmsgperbatch = -1;
119 static int hf_mq_id_maxtransmissionsize = -1;
120 static int hf_mq_id_maxmsgsize = -1;
121 static int hf_mq_id_sequencewrapvalue = -1;
122 static int hf_mq_id_channel = -1;
123 static int hf_mq_id_capflags = -1;
124 static int hf_mq_id_unknown5 = -1;
125 static int hf_mq_id_ccsid = -1;
126 static int hf_mq_id_queuemanager = -1;
127 static int hf_mq_id_heartbeatinterval = -1;
128 static int hf_mq_id_unknown6 = -1;
129 static int hf_mq_id_icf_msgseq = -1;
130 static int hf_mq_id_icf_convcap = -1;
131 static int hf_mq_id_icf_splitmsg = -1;
132 static int hf_mq_id_icf_mqreq = -1;
133 static int hf_mq_id_icf_svrsec = -1;
134 static int hf_mq_id_icf_runtime = -1;
135 static int hf_mq_id_ief_ccsid = -1;
136 static int hf_mq_id_ief_enc = -1;
137 static int hf_mq_id_ief_mxtrsz = -1;
138 static int hf_mq_id_ief_fap = -1;
139 static int hf_mq_id_ief_mxmsgsz = -1;
140 static int hf_mq_id_ief_mxmsgpb = -1;
141 static int hf_mq_id_ief_seqwrap = -1;
142 static int hf_mq_id_ief_hbint = -1;
143 static int hf_mq_uid_structid = -1;
144 static int hf_mq_uid_userid = -1;
145 static int hf_mq_uid_password = -1;
146 static int hf_mq_uid_longuserid = -1;
147 static int hf_mq_uid_securityid = -1;
148 static int hf_mq_conn_queuemanager = -1;
149 static int hf_mq_conn_appname = -1;
150 static int hf_mq_conn_apptype = -1;
151 static int hf_mq_conn_acttoken = -1;
152 static int hf_mq_conn_version = -1;
153 static int hf_mq_conn_options = -1;
154 static int hf_mq_inq_nbsel = -1;
155 static int hf_mq_inq_nbint = -1;
156 static int hf_mq_inq_charlen = -1;
157 static int hf_mq_inq_sel = -1;
158 static int hf_mq_inq_intvalue = -1;
159 static int hf_mq_inq_charvalues = -1;
160 static int hf_mq_spi_verb = -1;
161 static int hf_mq_spi_version = -1;
162 static int hf_mq_spi_length = -1;
163 static int hf_mq_spi_base_structid = -1;
164 static int hf_mq_spi_base_version = -1;
165 static int hf_mq_spi_base_length = -1;
166 static int hf_mq_spi_spqo_nbverb = -1;
167 static int hf_mq_spi_spqo_verbid = -1;
168 static int hf_mq_spi_spqo_maxinoutversion = -1;
169 static int hf_mq_spi_spqo_maxinversion = -1;
170 static int hf_mq_spi_spqo_maxoutversion = -1;
171 static int hf_mq_spi_spqo_flags = -1;
172 static int hf_mq_spi_spai_mode = -1;
173 static int hf_mq_spi_spai_unknown1 = -1;
174 static int hf_mq_spi_spai_unknown2 = -1;
175 static int hf_mq_spi_spai_msgid = -1;
176 static int hf_mq_spi_spgi_batchsize = -1;
177 static int hf_mq_spi_spgi_batchint = -1;
178 static int hf_mq_spi_spgi_maxmsgsize = -1;
179 static int hf_mq_spi_spgo_options = -1;
180 static int hf_mq_spi_spgo_size = -1;
181 static int hf_mq_spi_options_blank = -1;
182 static int hf_mq_spi_options_syncpoint = -1;
183 static int hf_mq_spi_options_deferred = -1;
184 static int hf_mq_put_length = -1;
185 static int hf_mq_open_options = -1;
186 static int hf_mq_ping_length = -1;
187 static int hf_mq_ping_buffer = -1;
188 static int hf_mq_reset_length = -1;
189 static int hf_mq_reset_seqnum = -1;
190 static int hf_mq_status_length = -1;
191 static int hf_mq_status_code = -1;
192 static int hf_mq_status_value = -1;
193 static int hf_mq_od_structid = -1;
194 static int hf_mq_od_version = -1;
195 static int hf_mq_od_objecttype = -1;
196 static int hf_mq_od_objectname = -1;
197 static int hf_mq_od_objectqmgrname = -1;
198 static int hf_mq_od_dynamicqname = -1;
199 static int hf_mq_od_alternateuserid = -1;
200 static int hf_mq_od_recspresent = -1;
201 static int hf_mq_od_knowndestcount = -1;
202 static int hf_mq_od_unknowndestcount = -1;
203 static int hf_mq_od_invaliddestcount = -1;
204 static int hf_mq_od_objectrecoffset = -1;
205 static int hf_mq_od_responserecoffset = -1;
206 static int hf_mq_od_objectrecptr = -1;
207 static int hf_mq_od_responserecptr = -1;
208 static int hf_mq_od_alternatesecurityid = -1;
209 static int hf_mq_od_resolvedqname = -1;
210 static int hf_mq_od_resolvedqmgrname = -1;
211 static int hf_mq_or_objname= -1;
212 static int hf_mq_or_objqmgrname = -1;
213 static int hf_mq_rr_completioncode = -1;
214 static int hf_mq_rr_reasoncode = -1;
215 static int hf_mq_pmr_msgid = -1;
216 static int hf_mq_pmr_correlid = -1;
217 static int hf_mq_pmr_groupid = -1;
218 static int hf_mq_pmr_feedback = -1;
219 static int hf_mq_pmr_acttoken = -1;
220 static int hf_mq_md_structid = -1;
221 static int hf_mq_md_version = -1;
222 static int hf_mq_md_report = -1;
223 static int hf_mq_md_msgtype = -1;
224 static int hf_mq_md_expiry = -1;
225 static int hf_mq_md_feedback = -1;
226 static int hf_mq_md_encoding = -1;
227 static int hf_mq_md_ccsid = -1;
228 static int hf_mq_md_format = -1;
229 static int hf_mq_md_priority = -1;
230 static int hf_mq_md_persistence = -1;
231 static int hf_mq_md_msgid = -1;
232 static int hf_mq_md_correlid = -1;
233 static int hf_mq_md_backountcount = -1;
234 static int hf_mq_md_replytoq = -1;
235 static int hf_mq_md_replytoqmgr = -1;
236 static int hf_mq_md_userid = -1;
237 static int hf_mq_md_acttoken = -1;
238 static int hf_mq_md_appliddata = -1;
239 static int hf_mq_md_putappltype = -1;
240 static int hf_mq_md_putapplname = -1;
241 static int hf_mq_md_putdate = -1;
242 static int hf_mq_md_puttime = -1;
243 static int hf_mq_md_applorigindata = -1;
244 static int hf_mq_md_groupid = -1;
245 static int hf_mq_md_msgseqnumber = -1;
246 static int hf_mq_md_offset = -1;
247 static int hf_mq_md_msgflags = -1;
248 static int hf_mq_md_originallength = -1;
249 static int hf_mq_md_hidden_lastformat = -1;
250 static int hf_mq_dlh_structid = -1;
251 static int hf_mq_dlh_version = -1;
252 static int hf_mq_dlh_reason = -1;
253 static int hf_mq_dlh_destq = -1;
254 static int hf_mq_dlh_destqmgr = -1;
255 static int hf_mq_dlh_encoding = -1;
256 static int hf_mq_dlh_ccsid = -1;
257 static int hf_mq_dlh_format = -1;
258 static int hf_mq_dlh_putappltype = -1;
259 static int hf_mq_dlh_putapplname = -1;
260 static int hf_mq_dlh_putdate = -1;
261 static int hf_mq_dlh_puttime = -1;
262 static int hf_mq_dh_putmsgrecfields = -1;
263 static int hf_mq_dh_recspresent = -1;
264 static int hf_mq_dh_objectrecoffset = -1;
265 static int hf_mq_dh_putmsgrecoffset = -1;
266 static int hf_mq_gmo_structid = -1;
267 static int hf_mq_gmo_version = -1;
268 static int hf_mq_gmo_options = -1;
269 static int hf_mq_gmo_waitinterval = -1;
270 static int hf_mq_gmo_signal1 = -1;
271 static int hf_mq_gmo_signal2 = -1;
272 static int hf_mq_gmo_resolvedqname = -1;
273 static int hf_mq_gmo_matchoptions = -1;
274 static int hf_mq_gmo_groupstatus = -1;
275 static int hf_mq_gmo_segmentstatus = -1;
276 static int hf_mq_gmo_segmentation = -1;
277 static int hf_mq_gmo_reserved = -1;
278 static int hf_mq_gmo_msgtoken = -1;
279 static int hf_mq_gmo_returnedlength = -1;
280 static int hf_mq_pmo_structid = -1;
281 static int hf_mq_pmo_version = -1;
282 static int hf_mq_pmo_options = -1;
283 static int hf_mq_pmo_timeout = -1;
284 static int hf_mq_pmo_context = -1;
285 static int hf_mq_pmo_knowndestcount = -1;
286 static int hf_mq_pmo_unknowndestcount = -1;
287 static int hf_mq_pmo_invaliddestcount = -1;
288 static int hf_mq_pmo_resolvedqname = -1;
289 static int hf_mq_pmo_resolvedqmgrname = -1;
290 static int hf_mq_pmo_recspresent = -1;
291 static int hf_mq_pmo_putmsgrecfields = -1;
292 static int hf_mq_pmo_putmsgrecoffset = -1;
293 static int hf_mq_pmo_responserecoffset = -1;
294 static int hf_mq_pmo_putmsgrecptr = -1;
295 static int hf_mq_pmo_responserecptr = -1;
296 static int hf_mq_head_structid = -1;
297 static int hf_mq_head_version = -1;
298 static int hf_mq_head_length = -1;
299 static int hf_mq_head_encoding = -1;
300 static int hf_mq_head_ccsid = -1;
301 static int hf_mq_head_format = -1;
302 static int hf_mq_head_flags = -1;
303 static int hf_mq_head_struct = -1;
304 static int hf_mq_xa_length = -1;
305 static int hf_mq_xa_returnvalue = -1;
306 static int hf_mq_xa_tmflags = -1;
307 static int hf_mq_xa_rmid = -1;
308 static int hf_mq_xa_count = -1;
309 static int hf_mq_xa_tmflags_join = -1;
310 static int hf_mq_xa_tmflags_endrscan = -1;
311 static int hf_mq_xa_tmflags_startrscan = -1;
312 static int hf_mq_xa_tmflags_suspend = -1;
313 static int hf_mq_xa_tmflags_success = -1;
314 static int hf_mq_xa_tmflags_resume = -1;
315 static int hf_mq_xa_tmflags_fail = -1;
316 static int hf_mq_xa_tmflags_onephase = -1;
317 static int hf_mq_xa_xid_formatid = -1;
318 static int hf_mq_xa_xid_globalxid_length = -1;
319 static int hf_mq_xa_xid_brq_length = -1;
320 static int hf_mq_xa_xid_globalxid = -1;
321 static int hf_mq_xa_xid_brq = -1;
322 static int hf_mq_xa_xainfo_length = -1;
323 static int hf_mq_xa_xainfo_value = -1;
324
325 static gint ett_mq = -1;
326 static gint ett_mq_tsh = -1;
327 static gint ett_mq_tsh_tcf = -1;
328 static gint ett_mq_api = -1;
329 static gint ett_mq_msh = -1;
330 static gint ett_mq_xqh = -1;
331 static gint ett_mq_id = -1;
332 static gint ett_mq_id_icf = -1;
333 static gint ett_mq_id_ief = -1;
334 static gint ett_mq_uid = -1;
335 static gint ett_mq_conn = -1;
336 static gint ett_mq_inq = -1;
337 static gint ett_mq_spi = -1;
338 static gint ett_mq_spi_base = -1; /* Factorisation of common SPI items */
339 static gint ett_mq_spi_options = -1;
340 static gint ett_mq_put = -1;
341 static gint ett_mq_open = -1;
342 static gint ett_mq_ping = -1;
343 static gint ett_mq_reset = -1;
344 static gint ett_mq_status = -1;
345 static gint ett_mq_od = -1;
346 static gint ett_mq_or = -1;
347 static gint ett_mq_rr = -1;
348 static gint ett_mq_pmr = -1;
349 static gint ett_mq_md = -1;
350 static gint ett_mq_mde = -1;
351 static gint ett_mq_dlh = -1;
352 static gint ett_mq_dh = -1;
353 static gint ett_mq_gmo = -1;
354 static gint ett_mq_pmo = -1;
355 static gint ett_mq_head = -1; /* Factorisation of common Header structure items (DH, MDE, CIH, IIH, RFH, RMH, WIH */
356 static gint ett_mq_xa = -1;
357 static gint ett_mq_xa_tmflags = -1;
358 static gint ett_mq_xa_xid = -1;
359 static gint ett_mq_xa_info = -1;
360
361 static dissector_handle_t mq_tcp_handle;
362 static dissector_handle_t mq_spx_handle;
363 static dissector_handle_t data_handle;
364
365 static heur_dissector_list_t mq_heur_subdissector_list;
366
367 static gboolean mq_desegment = TRUE;
368 static gboolean mq_reassembly = TRUE;
369
370 static GHashTable *mq_fragment_table = NULL;
371 static GHashTable *mq_reassembled_table = NULL;
372
373
374 #define MQ_PORT_TCP    1414
375 #define MQ_SOCKET_SPX  0x5E86
376
377 #define MQ_XPT_TCP      0x02
378 #define MQ_XPT_NETBIOS  0x03
379 #define MQ_XPT_SPX      0x04
380 #define MQ_XPT_HTTP     0x07
381
382 #define MQ_STRUCTID_NULL          0x00000000
383 #define MQ_STRUCTID_CIH           0x43494820
384 #define MQ_STRUCTID_DH            0x44482020
385 #define MQ_STRUCTID_DLH           0x444C4820
386 #define MQ_STRUCTID_GMO           0x474D4F20
387 #define MQ_STRUCTID_ID            0x49442020
388 #define MQ_STRUCTID_IIH           0x49494820
389 #define MQ_STRUCTID_MD            0x4D442020
390 #define MQ_STRUCTID_MDE           0x4D444520
391 #define MQ_STRUCTID_MSH           0x4D534820
392 #define MQ_STRUCTID_OD            0x4F442020
393 #define MQ_STRUCTID_PMO           0x504D4F20
394 #define MQ_STRUCTID_RFH           0x52464820
395 #define MQ_STRUCTID_RMH           0x524D4820
396 #define MQ_STRUCTID_TM            0x544D2020
397 #define MQ_STRUCTID_TMC2          0x544D4332
398 #define MQ_STRUCTID_TSH           0x54534820
399 #define MQ_STRUCTID_UID           0x55494420
400 #define MQ_STRUCTID_WIH           0x57494820
401 #define MQ_STRUCTID_XQH           0x58514820
402 #define MQ_STRUCTID_CIH_EBCDIC    0xC3C9C840
403 #define MQ_STRUCTID_DH_EBCDIC     0xC4C84040
404 #define MQ_STRUCTID_DLH_EBCDIC    0xC4D3C840
405 #define MQ_STRUCTID_GMO_EBCDIC    0xC7D4D640
406 #define MQ_STRUCTID_ID_EBCDIC     0xC9C44040
407 #define MQ_STRUCTID_IIH_EBCDIC    0xC9C9C840
408 #define MQ_STRUCTID_MD_EBCDIC     0xD4C44040
409 #define MQ_STRUCTID_MDE_EBCDIC    0xD4C4C540
410 #define MQ_STRUCTID_MSH_EBCDIC    0xD4E2C840
411 #define MQ_STRUCTID_OD_EBCDIC     0xD6C44040
412 #define MQ_STRUCTID_PMO_EBCDIC    0xD7D4D640
413 #define MQ_STRUCTID_RFH_EBCDIC    0xD9C6C840
414 #define MQ_STRUCTID_RMH_EBCDIC    0xD9D4C840
415 #define MQ_STRUCTID_TM_EBCDIC     0xE3D44040
416 #define MQ_STRUCTID_TMC2_EBCDIC   0xE3D4C3F2
417 #define MQ_STRUCTID_TSH_EBCDIC    0xE3E2C840
418 #define MQ_STRUCTID_UID_EBCDIC    0xE4C9C440
419 #define MQ_STRUCTID_WIH_EBCDIC    0xE6C9C840
420 #define MQ_STRUCTID_XQH_EBCDIC    0xE7D8C840
421
422 #define MQ_STRUCTID_SPQU          0x53505155 /* SPI Query InOut */
423 #define MQ_STRUCTID_SPQI          0x53505149 /* SPI Query In */
424 #define MQ_STRUCTID_SPQO          0x5350514F /* SPI Query Out */
425 #define MQ_STRUCTID_SPPU          0x53505055 /* SPI Put InOut */
426 #define MQ_STRUCTID_SPPI          0x53505049 /* SPI Put In */
427 #define MQ_STRUCTID_SPPO          0x5350504F /* SPI Put Out */
428 #define MQ_STRUCTID_SPGU          0x53504755 /* SPI Get InOut */
429 #define MQ_STRUCTID_SPGI          0x53504749 /* SPI Get In */
430 #define MQ_STRUCTID_SPGO          0x5350474F /* SPI Get Out */
431 #define MQ_STRUCTID_SPAU          0x53504155 /* SPI Activate InOut */
432 #define MQ_STRUCTID_SPAI          0x53504149 /* SPI Activate In */
433 #define MQ_STRUCTID_SPAO          0x5350414F /* SPI Activate Out */
434 #define MQ_STRUCTID_SPQU_EBCDIC   0xE2D7D8E4 /* SPI Query InOut */
435 #define MQ_STRUCTID_SPQI_EBCDIC   0xE2D7D8C9 /* SPI Query In */
436 #define MQ_STRUCTID_SPQO_EBCDIC   0xE2D7D8D6 /* SPI Query Out */
437 #define MQ_STRUCTID_SPPU_EBCDIC   0xE2D7D7E4 /* SPI Put InOut */
438 #define MQ_STRUCTID_SPPI_EBCDIC   0xE2D7D7C9 /* SPI Put In */
439 #define MQ_STRUCTID_SPPO_EBCDIC   0xE2D7D7D6 /* SPI Put Out */
440 #define MQ_STRUCTID_SPGU_EBCDIC   0xE2D7C7E4 /* SPI Get InOut */
441 #define MQ_STRUCTID_SPGI_EBCDIC   0xE2D7C7C9 /* SPI Get In */
442 #define MQ_STRUCTID_SPGO_EBCDIC   0xE2D7C7D6 /* SPI Get Out */
443 #define MQ_STRUCTID_SPAU_EBCDIC   0xE2D7C1E4 /* SPI Activate InOut */
444 #define MQ_STRUCTID_SPAI_EBCDIC   0xE2D7C1C9 /* SPI Activate In */
445 #define MQ_STRUCTID_SPAO_EBCDIC   0xE2D7C1D6 /* SPI Activate Out */
446
447 #define MQ_TST_INITIAL            0x01
448 #define MQ_TST_RESYNC             0x02
449 #define MQ_TST_RESET              0x03
450 #define MQ_TST_MESSAGE            0x04
451 #define MQ_TST_STATUS             0x05
452 #define MQ_TST_SECURITY           0x06
453 #define MQ_TST_PING               0x07
454 #define MQ_TST_USERID             0x08
455 #define MQ_TST_HEARTBEAT          0x09
456 #define MQ_TST_MQCONN             0x81
457 #define MQ_TST_MQDISC             0x82
458 #define MQ_TST_MQOPEN             0x83
459 #define MQ_TST_MQCLOSE            0x84
460 #define MQ_TST_MQGET              0x85
461 #define MQ_TST_MQPUT              0x86
462 #define MQ_TST_MQPUT1             0x87
463 #define MQ_TST_MQSET              0x88
464 #define MQ_TST_MQINQ              0x89
465 #define MQ_TST_MQCMIT             0x8A
466 #define MQ_TST_MQBACK             0x8B
467 #define MQ_TST_SPI                0x8C
468 #define MQ_TST_MQCONN_REPLY       0x91
469 #define MQ_TST_MQDISC_REPLY       0x92
470 #define MQ_TST_MQOPEN_REPLY       0x93
471 #define MQ_TST_MQCLOSE_REPLY      0x94
472 #define MQ_TST_MQGET_REPLY        0x95
473 #define MQ_TST_MQPUT_REPLY        0x96
474 #define MQ_TST_MQPUT1_REPLY       0x97
475 #define MQ_TST_MQSET_REPLY        0x98
476 #define MQ_TST_MQINQ_REPLY        0x99
477 #define MQ_TST_MQCMIT_REPLY       0x9A
478 #define MQ_TST_MQBACK_REPLY       0x9B
479 #define MQ_TST_SPI_REPLY          0x9C
480 #define MQ_TST_XA_START           0xA1
481 #define MQ_TST_XA_END             0xA2
482 #define MQ_TST_XA_OPEN            0xA3
483 #define MQ_TST_XA_CLOSE           0xA4
484 #define MQ_TST_XA_PREPARE         0xA5
485 #define MQ_TST_XA_COMMIT          0xA6
486 #define MQ_TST_XA_ROLLBACK        0xA7
487 #define MQ_TST_XA_FORGET          0xA8
488 #define MQ_TST_XA_RECOVER         0xA9
489 #define MQ_TST_XA_COMPLETE        0xAA
490 #define MQ_TST_XA_START_REPLY     0xB1
491 #define MQ_TST_XA_END_REPLY       0xB2
492 #define MQ_TST_XA_OPEN_REPLY      0xB3
493 #define MQ_TST_XA_CLOSE_REPLY     0xB4
494 #define MQ_TST_XA_PREPARE_REPLY   0xB5
495 #define MQ_TST_XA_COMMIT_REPLY    0xB6
496 #define MQ_TST_XA_ROLLBACK_REPLY  0xB7
497 #define MQ_TST_XA_FORGET_REPLY    0xB8
498 #define MQ_TST_XA_RECOVER_REPLY   0xB9
499 #define MQ_TST_XA_COMPLETE_REPLY  0xBA
500
501 #define MQ_SPI_QUERY              0x01
502 #define MQ_SPI_PUT                0x02
503 #define MQ_SPI_GET                0x03
504 #define MQ_SPI_ACTIVATE           0x04
505
506 #define MQ_SPI_ACTIVATE_ENABLE    0x01
507 #define MQ_SPI_ACTIVATE_DISABLE   0x02
508
509 #define MQ_SPI_OPTIONS_BLANK_PADDED  0x01
510 #define MQ_SPI_OPTIONS_SYNCPOINT     0x02
511 #define MQ_SPI_OPTIONS_DEFERRED      0x04
512
513 #define MQ_TCF_CONFIRM_REQUEST    0x01
514 #define MQ_TCF_ERROR              0x02
515 #define MQ_TCF_REQUEST_CLOSE      0x04
516 #define MQ_TCF_CLOSE_CHANNEL      0x08
517 #define MQ_TCF_FIRST              0x10
518 #define MQ_TCF_LAST               0x20
519 #define MQ_TCF_REQUEST_ACCEPTED   0x40
520 #define MQ_TCF_DLQ_USED           0x80
521
522 #define MQ_ICF_MSG_SEQ            0x01
523 #define MQ_ICF_CONVERSION_CAPABLE 0x02
524 #define MQ_ICF_SPLIT_MESSAGE      0x04
525 #define MQ_ICF_MQREQUEST          0x20
526 #define MQ_ICF_SVRCONN_SECURITY   0x40
527 #define MQ_ICF_RUNTIME            0x80
528
529 #define MQ_IEF_CCSID                  0x01
530 #define MQ_IEF_ENCODING               0x02
531 #define MQ_IEF_MAX_TRANSMISSION_SIZE  0x04
532 #define MQ_IEF_FAP_LEVEL              0x08
533 #define MQ_IEF_MAX_MSG_SIZE           0x10
534 #define MQ_IEF_MAX_MSG_PER_BATCH      0x20
535 #define MQ_IEF_SEQ_WRAP_VALUE         0x40
536 #define MQ_IEF_HEARTBEAT_INTERVAL     0x80
537
538 #define MQ_BIG_ENDIAN          0x01
539 #define MQ_LITTLE_ENDIAN       0x02
540
541 #define MQ_CONN_VERSION        0x01
542 #define MQ_CONNX_VERSION       0x03
543
544 #define MQ_STATUS_E_REMOTE_CHANNEL_NOT_FOUND   0x01
545 #define MQ_STATUS_E_BAD_REMOTE_CHANNEL_TYPE    0x02
546 #define MQ_STATUS_E_REMOTE_QM_UNAVAILABLE      0x03
547 #define MQ_STATUS_E_MSG_SEQUENCE_ERROR         0x04
548 #define MQ_STATUS_E_REMOTE_QM_TERMINATING      0x05
549 #define MQ_STATUS_E_MSG_NOT_RECEIVED           0x06
550 #define MQ_STATUS_I_CHANNEL_CLOSED             0x07
551 #define MQ_STATUS_I_DISCINTERVAL_EXPIRED       0x08
552 #define MQ_STATUS_E_REMOTE_PROTOCOL_ERROR      0x0A
553 #define MQ_STATUS_E_BIND_FAILED                0x14
554 #define MQ_STATUS_E_MSGWRAP_DIFFERENT          0x15
555 #define MQ_STATUS_E_REMOTE_CHANNEL_UNAVAILABLE 0x16
556 #define MQ_STATUS_E_TERMINATED_BY_REMOTE_EXIT  0x17
557 #define MQ_STATUS_E_SSL_REMOTE_BAD_CIPHER      0x18
558
559 /* These errors codes are documented in javax.transaction.xa.XAException */
560 #define MQ_XA_RBROLLBACK   100
561 #define MQ_XA_RBCOMMFAIL   101
562 #define MQ_XA_RBDEADLOCK   102
563 #define MQ_XA_RBINTEGRITY  103
564 #define MQ_XA_RBOTHER      104
565 #define MQ_XA_RBPROTO      105
566 #define MQ_XA_RBTIMEOUT    106
567 #define MQ_XA_RBTRANSIENT  107
568 #define MQ_XA_NOMIGRATE    9
569 #define MQ_XA_HEURHAZ      8
570 #define MQ_XA_HEURCOM      7
571 #define MQ_XA_HEURRB       6
572 #define MQ_XA_HEURMIX      5
573 #define MQ_XA_RETRY        4
574 #define MQ_XA_RDONLY       3
575 #define MQ_XA_OK           0
576 #define MQ_XAER_ASYNC      -2
577 #define MQ_XAER_RMERR      -3
578 #define MQ_XAER_NOTA       -4
579 #define MQ_XAER_INVAL      -5
580 #define MQ_XAER_PROTO      -6
581 #define MQ_XAER_RMFAIL     -7
582 #define MQ_XAER_DUPID      -8
583 #define MQ_XAER_OUTSIDE    -9
584
585 /* These flags are documented in javax.transaction.xa.XAResource */
586 #define MQ_XA_TMNOFLAGS     0
587 #define MQ_XA_TMJOIN        0x200000
588 #define MQ_XA_TMENDRSCAN    0x800000
589 #define MQ_XA_TMSTARTRSCAN  0x1000000
590 #define MQ_XA_TMSUSPEND     0x2000000
591 #define MQ_XA_TMSUCCESS     0x4000000
592 #define MQ_XA_TMRESUME      0x8000000
593 #define MQ_XA_TMFAIL        0x20000000
594 #define MQ_XA_TMONEPHASE    0x40000000
595
596 #define MQ_PMRF_NONE              0x00
597 #define MQ_PMRF_MSG_ID            0x01
598 #define MQ_PMRF_CORREL_ID         0x02
599 #define MQ_PMRF_GROUP_ID          0x04
600 #define MQ_PMRF_FEEDBACK          0x08
601 #define MQ_PMRF_ACCOUNTING_TOKEN  0x10
602
603 /* MQ structures */
604 /* Undocumented structures */
605 #define MQ_TEXT_TSH   "Transmission Segment Header"
606 #define MQ_TEXT_API   "API Header"
607 #define MQ_TEXT_ID    "Initial Data"
608 #define MQ_TEXT_UID   "User Id Data"
609 #define MQ_TEXT_MSH   "Message Segment Header"
610 #define MQ_TEXT_CONN  "MQCONN"
611 #define MQ_TEXT_INQ   "MQINQ/MQSET"
612 #define MQ_TEXT_PUT   "MQPUT/MQGET"
613 #define MQ_TEXT_OPEN  "MQOPEN/MQCLOSE"
614 #define MQ_TEXT_PING  "PING"
615 #define MQ_TEXT_RESET "RESET"
616 #define MQ_TEXT_STAT  "STATUS"
617 #define MQ_TEXT_SPI   "SPI"
618 #define MQ_TEXT_XA    "XA"
619 #define MQ_TEXT_XID   "Xid"
620 #define MQ_TEXT_XINF  "XA_info"
621
622 /* Documented structures with structid */
623 #define MQ_TEXT_CIH  "CICS bridge Header"
624 #define MQ_TEXT_DH   "Distribution Header"
625 #define MQ_TEXT_DLH  "Dead-Letter Header"
626 #define MQ_TEXT_GMO  "Get Message Options"
627 #define MQ_TEXT_IIH  "IMS Information Header"
628 #define MQ_TEXT_MD   "Message Descriptor"
629 #define MQ_TEXT_MDE  "Message Descriptor Extension"
630 #define MQ_TEXT_OD   "Object Descriptor"
631 #define MQ_TEXT_PMO  "Put Message Options"
632 #define MQ_TEXT_RMH  "Reference Message Header"
633 #define MQ_TEXT_TM   "Trigger Message"
634 #define MQ_TEXT_TMC2 "Trigger Message 2 (character format)"
635 #define MQ_TEXT_WIH  "Work Information Header"
636 #define MQ_TEXT_XQH  "Transmission Queue Header"
637
638 /* Documented structures without structid */
639 #define MQ_TEXT_OR   "Object Record"
640 #define MQ_TEXT_PMR  "Put Message Record"
641 #define MQ_TEXT_RR   "Response Record"
642
643
644 static const value_string mq_opcode_vals[] = {
645   { MQ_TST_INITIAL,           "INITIAL_DATA" },
646   { MQ_TST_RESYNC,            "RESYNC_DATA" },
647   { MQ_TST_RESET,             "RESET_DATA" },
648   { MQ_TST_MESSAGE,           "MESSAGE_DATA" },
649   { MQ_TST_STATUS,            "STATUS_DATA" },
650   { MQ_TST_SECURITY,          "SECURITY_DATA" },
651   { MQ_TST_PING,              "PING_DATA" },
652   { MQ_TST_USERID,            "USERID_DATA" },
653   { MQ_TST_HEARTBEAT,         "HEARTBEAT" },
654   { MQ_TST_MQCONN,            "MQCONN" },
655   { MQ_TST_MQDISC,            "MQDISC" },
656   { MQ_TST_MQOPEN,            "MQOPEN" },
657   { MQ_TST_MQCLOSE,           "MQCLOSE" },
658   { MQ_TST_MQGET,             "MQGET" },
659   { MQ_TST_MQPUT,             "MQPUT" },
660   { MQ_TST_MQPUT1,            "MQPUT1" },
661   { MQ_TST_MQSET,             "MQSET" },
662   { MQ_TST_MQINQ,             "MQINQ" },
663   { MQ_TST_MQCMIT,            "MQCMIT" },
664   { MQ_TST_MQBACK,            "MQBACK" },
665   { MQ_TST_SPI,               "SPI" },
666   { MQ_TST_MQCONN_REPLY,      "MQCONN_REPLY" },
667   { MQ_TST_MQDISC_REPLY,      "MQDISC_REPLY" },
668   { MQ_TST_MQOPEN_REPLY,      "MQOPEN_REPLY" },
669   { MQ_TST_MQCLOSE_REPLY,     "MQCLOSE_REPLY" },
670   { MQ_TST_MQGET_REPLY,       "MQGET_REPLY" },
671   { MQ_TST_MQPUT_REPLY,       "MQPUT_REPLY" },
672   { MQ_TST_MQPUT1_REPLY,      "MQPUT1_REPLY" },
673   { MQ_TST_MQSET_REPLY,       "MQSET_REPLY" },
674   { MQ_TST_MQINQ_REPLY,       "MQINQ_REPLY" },
675   { MQ_TST_MQCMIT_REPLY,      "MQCMIT_REPLY" },
676   { MQ_TST_MQBACK_REPLY,      "MQBACK_REPLY" },
677   { MQ_TST_SPI_REPLY,         "SPI_REPLY" },
678   { MQ_TST_XA_START,          "XA_START" },
679   { MQ_TST_XA_END,            "XA_END" },
680   { MQ_TST_XA_OPEN,           "XA_OPEN" },
681   { MQ_TST_XA_CLOSE,          "XA_CLOSE" },
682   { MQ_TST_XA_PREPARE,        "XA_PREPARE" },
683   { MQ_TST_XA_COMMIT,         "XA_COMMIT" },
684   { MQ_TST_XA_ROLLBACK,       "XA_ROLLBACK" },
685   { MQ_TST_XA_FORGET,         "XA_FORGET" },
686   { MQ_TST_XA_RECOVER,        "XA_RECOVER" },
687   { MQ_TST_XA_COMPLETE,       "XA_COMPLETE" },
688   { MQ_TST_XA_START_REPLY,    "XA_START_REPLY" },
689   { MQ_TST_XA_END_REPLY,      "XA_END_REPLY" },
690   { MQ_TST_XA_OPEN_REPLY,     "XA_OPEN_REPLY" },
691   { MQ_TST_XA_CLOSE_REPLY,    "XA_CLOSE_REPLY" },
692   { MQ_TST_XA_PREPARE_REPLY,  "XA_PREPARE_REPLY" },
693   { MQ_TST_XA_COMMIT_REPLY,   "XA_COMMIT_REPLY" },
694   { MQ_TST_XA_ROLLBACK_REPLY, "XA_ROLLBACK_REPLY" },
695   { MQ_TST_XA_FORGET_REPLY,   "XA_FORGET_REPLY" },
696   { MQ_TST_XA_RECOVER_REPLY,  "XA_RECOVER_REPLY" },
697   { MQ_TST_XA_COMPLETE_REPLY, "XA_COMPLETE_REPLY" },
698   { 0,          NULL }
699 };
700
701 static const value_string mq_spi_verbs_vals[] = {
702   { MQ_SPI_QUERY,      "QUERY" },
703   { MQ_SPI_PUT,        "PUT" },
704   { MQ_SPI_GET,        "GET" },
705   { MQ_SPI_ACTIVATE,   "ACTIVATE" },
706   { 0,          NULL }
707 };
708
709 static const value_string mq_spi_activate_vals[] = {
710   { MQ_SPI_ACTIVATE_ENABLE,      "ENABLE" },
711   { MQ_SPI_ACTIVATE_DISABLE,     "DISABLE" },
712   { 0,          NULL }
713 };
714
715 static const value_string mq_status_vals[] = {
716   { MQ_STATUS_E_REMOTE_CHANNEL_NOT_FOUND,    "REMOTE_CHANNEL_NOT_FOUND" },
717   { MQ_STATUS_E_BAD_REMOTE_CHANNEL_TYPE,     "BAD_REMOTE_CHANNEL_TYPE" },
718   { MQ_STATUS_E_REMOTE_QM_UNAVAILABLE,       "REMOTE_QM_UNAVAILABLE" },
719   { MQ_STATUS_E_MSG_SEQUENCE_ERROR,          "MSG_SEQUENCE_ERROR" },
720   { MQ_STATUS_E_REMOTE_QM_TERMINATING,       "REMOTE_QM_TERMINATING" },
721   { MQ_STATUS_E_MSG_NOT_RECEIVED,            "MSG_NOT_RECEIVED" },
722   { MQ_STATUS_I_CHANNEL_CLOSED,              "CHANNEL_CLOSED" },
723   { MQ_STATUS_I_DISCINTERVAL_EXPIRED,        "DISCINTERVAL_EXPIRED" },
724   { MQ_STATUS_E_REMOTE_PROTOCOL_ERROR,       "REMOTE_PROTOCOL_ERROR" },
725   { MQ_STATUS_E_BIND_FAILED,                 "BIND_FAILED" },
726   { MQ_STATUS_E_MSGWRAP_DIFFERENT,           "MSGWRAP_DIFFERENT" },
727   { MQ_STATUS_E_REMOTE_CHANNEL_UNAVAILABLE,  "REMOTE_CHANNEL_UNAVAILABLE" },
728   { MQ_STATUS_E_TERMINATED_BY_REMOTE_EXIT,   "TERMINATED_BY_REMOTE_EXIT" },
729   { MQ_STATUS_E_SSL_REMOTE_BAD_CIPHER,       "SSL_REMOTE_BAD_CIPHER" },
730   { 0,          NULL }
731 };
732
733 static const value_string mq_xaer_vals[] = {
734   { MQ_XA_RBROLLBACK,         "XA_RBROLLBACK" },
735   { MQ_XA_RBCOMMFAIL,         "XA_RBCOMMFAIL" },
736   { MQ_XA_RBDEADLOCK,         "XA_RBDEADLOCK" },
737   { MQ_XA_RBINTEGRITY,        "XA_RBINTEGRITY" },
738   { MQ_XA_RBOTHER,            "XA_RBOTHER" },
739   { MQ_XA_RBPROTO,            "XA_RBPROTO" },
740   { MQ_XA_RBTIMEOUT,          "XA_RBTIMEOUT" },
741   { MQ_XA_RBTRANSIENT,        "XA_RBTRANSIENT" },
742   { MQ_XA_NOMIGRATE,          "XA_NOMIGRATE" },
743   { MQ_XA_HEURHAZ,            "XA_HEURHAZ" },
744   { MQ_XA_HEURCOM,            "XA_HEURCOM" },
745   { MQ_XA_HEURRB,             "XA_HEURRB" },
746   { MQ_XA_HEURMIX,            "XA_HEURMIX" },
747   { MQ_XA_RETRY,              "XA_RETRY" },
748   { MQ_XA_RDONLY,             "XA_RDONLY" },
749   { MQ_XA_OK,                 "XA_OK" },
750   { (guint32)MQ_XAER_ASYNC,   "XAER_ASYNC" },
751   { (guint32)MQ_XAER_RMERR,   "XAER_RMERR" },
752   { (guint32)MQ_XAER_NOTA,    "XAER_NOTA" },
753   { (guint32)MQ_XAER_INVAL,   "XAER_INVAL" },
754   { (guint32)MQ_XAER_PROTO,   "XAER_PROTO" },
755   { (guint32)MQ_XAER_RMFAIL,  "XAER_RMFAIL" },
756   { (guint32)MQ_XAER_DUPID,   "XAER_DUPID" },
757   { (guint32)MQ_XAER_OUTSIDE, "XAER_OUTSIDE" },
758   { 0,          NULL }
759 };
760
761 static const value_string mq_structid_vals[] = {
762   { MQ_STRUCTID_CIH,         MQ_TEXT_CIH },
763   { MQ_STRUCTID_DH,          MQ_TEXT_DH },
764   { MQ_STRUCTID_DLH,         MQ_TEXT_DLH },
765   { MQ_STRUCTID_GMO,         MQ_TEXT_GMO },
766   { MQ_STRUCTID_ID,          MQ_TEXT_ID },
767   { MQ_STRUCTID_IIH,         MQ_TEXT_IIH },
768   { MQ_STRUCTID_MD,          MQ_TEXT_MD },
769   { MQ_STRUCTID_MDE,         MQ_TEXT_MDE },
770   { MQ_STRUCTID_MSH,         MQ_TEXT_MSH },
771   { MQ_STRUCTID_OD,          MQ_TEXT_OD },
772   { MQ_STRUCTID_PMO,         MQ_TEXT_PMO },
773   { MQ_STRUCTID_RMH,         MQ_TEXT_RMH },
774   { MQ_STRUCTID_TM,          MQ_TEXT_TM },
775   { MQ_STRUCTID_TMC2,        MQ_TEXT_TMC2 },
776   { MQ_STRUCTID_TSH,         MQ_TEXT_TSH },
777   { MQ_STRUCTID_UID,         MQ_TEXT_UID },
778   { MQ_STRUCTID_WIH,         MQ_TEXT_WIH },
779   { MQ_STRUCTID_XQH,         MQ_TEXT_XQH },
780   { MQ_STRUCTID_CIH_EBCDIC,  MQ_TEXT_CIH },
781   { MQ_STRUCTID_DH_EBCDIC,   MQ_TEXT_DH },
782   { MQ_STRUCTID_DLH_EBCDIC,  MQ_TEXT_DLH },
783   { MQ_STRUCTID_GMO_EBCDIC,  MQ_TEXT_GMO },
784   { MQ_STRUCTID_ID_EBCDIC,   MQ_TEXT_ID },
785   { MQ_STRUCTID_IIH_EBCDIC,  MQ_TEXT_IIH },
786   { MQ_STRUCTID_MD_EBCDIC,   MQ_TEXT_MD },
787   { MQ_STRUCTID_MDE_EBCDIC,  MQ_TEXT_MDE },
788   { MQ_STRUCTID_OD_EBCDIC,   MQ_TEXT_OD },
789   { MQ_STRUCTID_PMO_EBCDIC,  MQ_TEXT_PMO },
790   { MQ_STRUCTID_RMH_EBCDIC,  MQ_TEXT_RMH },
791   { MQ_STRUCTID_TM_EBCDIC,   MQ_TEXT_TM },
792   { MQ_STRUCTID_TMC2_EBCDIC, MQ_TEXT_TMC2 },
793   { MQ_STRUCTID_TSH_EBCDIC,  MQ_TEXT_TSH },
794   { MQ_STRUCTID_UID_EBCDIC,  MQ_TEXT_UID },
795   { MQ_STRUCTID_WIH_EBCDIC,  MQ_TEXT_WIH },
796   { MQ_STRUCTID_XQH_EBCDIC,  MQ_TEXT_XQH },
797   { 0,          NULL }
798 };
799
800 static const value_string mq_byteorder_vals[] = {
801   { MQ_LITTLE_ENDIAN,  "Little endian" },
802   { MQ_BIG_ENDIAN,     "Big endian" },
803   { 0,          NULL }
804 };
805
806 static const value_string mq_conn_version_vals[] = {
807   { MQ_CONN_VERSION,   "MQCONN" },
808   { MQ_CONNX_VERSION,  "MQCONNX" },
809   { 0,          NULL }
810 };
811
812 struct mq_msg_properties {
813         gint iOffsetEncoding;     /* Message encoding */
814         gint iOffsetCcsid;        /* Message character set */
815         gint iOffsetFormat;       /* Message format */
816 };
817
818 static guint32 tvb_get_guint32_endian(tvbuff_t *a_tvb, gint a_iOffset, gboolean a_bLittleEndian)
819 {
820         guint32 iResult;
821         if (a_bLittleEndian)
822                 iResult = tvb_get_letohl(a_tvb, a_iOffset);
823         else
824                 iResult =  tvb_get_ntohl(a_tvb, a_iOffset);
825         return iResult;
826 }
827
828 /* This routine truncates the string at the first blank space */
829 static gint strip_trailing_blanks(guint8* a_string, gint a_size)
830 {
831         gint i = 0;
832         if (a_string != NULL)
833         {
834                 for (i = 0; i < a_size; i++)
835                 {
836                         if (a_string[i] == ' ' || a_string[i] == '\0')
837                         {
838                                 a_string[i] = '\0';
839                                 break;
840                         }
841                 }
842         }
843         return i;
844 }
845
846 static gint
847 dissect_mq_md(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, struct mq_msg_properties* tMsgProps)
848 {
849         proto_tree      *mq_tree = NULL;
850         guint32 structId;
851         gint iSizeMD = 0;
852
853         if (tvb_length_remaining(tvb, offset) >= 4)
854         {
855                 structId = tvb_get_ntohl(tvb, offset);
856                 if ((structId == MQ_STRUCTID_MD || structId == MQ_STRUCTID_MD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
857                 {
858                         guint32 iVersionMD = 0;
859                         iVersionMD = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
860                         /* Compute length according to version */
861                         switch (iVersionMD)
862                         {
863                                 case 1: iSizeMD = 324; break;
864                                 case 2: iSizeMD = 364; break;
865                         }
866
867                         if (iSizeMD != 0 && tvb_length_remaining(tvb, offset) >= iSizeMD)
868                         {
869                                 tMsgProps->iOffsetEncoding = offset + 24;
870                                 tMsgProps->iOffsetCcsid    = offset + 28;
871                                 tMsgProps->iOffsetFormat   = offset + 32;
872                                 if (tree)
873                                 {
874                                         proto_item      *ti = NULL;
875                                         ti = proto_tree_add_text(tree, tvb, offset, iSizeMD, MQ_TEXT_MD);
876                                         mq_tree = proto_item_add_subtree(ti, ett_mq_md);
877
878                                         proto_tree_add_item(mq_tree, hf_mq_md_structid, tvb, offset, 4, FALSE);
879                                         proto_tree_add_item(mq_tree, hf_mq_md_version, tvb, offset + 4, 4, bLittleEndian);
880                                         proto_tree_add_item(mq_tree, hf_mq_md_report, tvb, offset + 8, 4, bLittleEndian);
881                                         proto_tree_add_item(mq_tree, hf_mq_md_msgtype, tvb, offset + 12, 4, bLittleEndian);
882                                         proto_tree_add_item(mq_tree, hf_mq_md_expiry, tvb, offset + 16, 4, bLittleEndian);
883                                         proto_tree_add_item(mq_tree, hf_mq_md_feedback, tvb, offset + 20, 4, bLittleEndian);
884                                         proto_tree_add_item(mq_tree, hf_mq_md_encoding, tvb, offset + 24, 4, bLittleEndian);
885                                         proto_tree_add_item(mq_tree, hf_mq_md_ccsid, tvb, offset + 28, 4, bLittleEndian);
886                                         proto_tree_add_item(mq_tree, hf_mq_md_format, tvb, offset + 32, 8, FALSE);
887                                         proto_tree_add_item(mq_tree, hf_mq_md_priority, tvb, offset + 40, 4, bLittleEndian);
888                                         proto_tree_add_item(mq_tree, hf_mq_md_persistence, tvb, offset + 44, 4, bLittleEndian);
889                                         proto_tree_add_item(mq_tree, hf_mq_md_msgid, tvb, offset + 48, 24, FALSE);
890                                         proto_tree_add_item(mq_tree, hf_mq_md_correlid, tvb, offset + 72, 24, FALSE);
891                                         proto_tree_add_item(mq_tree, hf_mq_md_backountcount, tvb, offset + 96, 4, bLittleEndian);
892                                         proto_tree_add_item(mq_tree, hf_mq_md_replytoq, tvb, offset + 100, 48, FALSE);
893                                         proto_tree_add_item(mq_tree, hf_mq_md_replytoqmgr, tvb, offset + 148, 48, FALSE);
894                                         proto_tree_add_item(mq_tree, hf_mq_md_userid, tvb, offset + 196, 12, FALSE);
895                                         proto_tree_add_item(mq_tree, hf_mq_md_acttoken, tvb, offset + 208, 32, FALSE);
896                                         proto_tree_add_item(mq_tree, hf_mq_md_appliddata, tvb, offset + 240, 32, FALSE);
897                                         proto_tree_add_item(mq_tree, hf_mq_md_putappltype, tvb, offset + 272, 4, bLittleEndian);
898                                         proto_tree_add_item(mq_tree, hf_mq_md_putapplname, tvb, offset + 276, 28, FALSE);
899                                         proto_tree_add_item(mq_tree, hf_mq_md_putdate, tvb, offset + 304, 8, FALSE);
900                                         proto_tree_add_item(mq_tree, hf_mq_md_puttime, tvb, offset + 312, 8, FALSE);
901                                         proto_tree_add_item(mq_tree, hf_mq_md_applorigindata, tvb, offset + 320, 4, FALSE);
902
903                                         if (iVersionMD >= 2)
904                                         {
905                                                 proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 324, 24, FALSE);
906                                                 proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 348, 4, bLittleEndian);
907                                                 proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 352, 4, bLittleEndian);
908                                                 proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 356, 4, bLittleEndian);
909                                                 proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 360, 4, bLittleEndian);
910                                         }
911                                 }
912                         }
913                 }
914         }
915         return iSizeMD;
916 }
917
918
919 static gint
920 dissect_mq_or(tvbuff_t *tvb, proto_tree *tree, gint offset, gint iNbrRecords, gint offsetOR)
921 {
922         proto_tree      *mq_tree = NULL;
923         proto_item      *ti = NULL;
924         gint iSizeOR = 0;
925         if (offsetOR != 0)
926         {
927                 iSizeOR = iNbrRecords * 96;
928                 if (tvb_length_remaining(tvb, offset) >= iSizeOR)
929                 {
930                         if (tree)
931                         {
932                                 gint iOffsetOR = 0;
933                                 gint iRecord = 0;
934                                 for (iRecord = 0; iRecord < iNbrRecords ; iRecord++)
935                                 {
936                                         ti = proto_tree_add_text(tree, tvb, offset + iOffsetOR, 96, MQ_TEXT_OR);
937                                         mq_tree = proto_item_add_subtree(ti, ett_mq_or);
938                                         proto_tree_add_item(mq_tree, hf_mq_or_objname, tvb, offset + iOffsetOR, 48, FALSE);
939                                         proto_tree_add_item(mq_tree, hf_mq_or_objqmgrname, tvb, offset + iOffsetOR + 48, 48, FALSE);
940                                         iOffsetOR += 96;
941                                 }
942                         }
943                 }
944                 else iSizeOR = 0;
945         }
946         return iSizeOR;
947 }
948
949 static gint
950 dissect_mq_rr(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetRR)
951 {
952         proto_tree      *mq_tree = NULL;
953         proto_item      *ti = NULL;
954         gint iSizeRR = 0;
955         if (offsetRR != 0)
956         {
957                 iSizeRR = iNbrRecords * 8;
958                 if (tvb_length_remaining(tvb, offset) >= iSizeRR)
959                 {
960                         if (tree)
961                         {
962                                 gint iOffsetRR = 0;
963                                 gint iRecord = 0;
964                                 for (iRecord = 0; iRecord < iNbrRecords; iRecord++)
965                                 {
966                                         ti = proto_tree_add_text(tree, tvb, offset + iOffsetRR, 8, MQ_TEXT_RR);
967                                         mq_tree = proto_item_add_subtree(ti, ett_mq_rr);
968                                         proto_tree_add_item(mq_tree, hf_mq_rr_completioncode, tvb, offset + iOffsetRR, 4, bLittleEndian);
969                                         proto_tree_add_item(mq_tree, hf_mq_rr_reasoncode, tvb, offset + iOffsetRR + 4, 4, bLittleEndian);
970                                         iOffsetRR += 8;
971                                 }
972                         }
973                 }
974                 else iSizeRR = 0;
975         }
976         return iSizeRR;
977 }
978
979 static gint
980 dissect_mq_pmr(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset, gint iNbrRecords, gint offsetPMR, guint32 recFlags)
981 {
982         proto_tree      *mq_tree = NULL;
983         proto_item      *ti = NULL;
984         gint iSizePMR1 = 0;
985         gint iSizePMR = 0;
986
987         iSizePMR1 =  ((((recFlags & MQ_PMRF_MSG_ID) != 0) * 24)
988                                         +(((recFlags & MQ_PMRF_CORREL_ID) != 0) * 24)
989                                         +(((recFlags & MQ_PMRF_GROUP_ID) != 0) * 24)
990                                         +(((recFlags & MQ_PMRF_FEEDBACK) != 0) * 4)
991                                         +(((recFlags & MQ_PMRF_ACCOUNTING_TOKEN) != 0) * 32));
992         if (offsetPMR != 0)
993         {
994                 iSizePMR = iNbrRecords * iSizePMR1;
995                 if (tvb_length_remaining(tvb, offset) >= iSizePMR)
996                 {
997                         if (tree)
998                         {
999                                 gint iOffsetPMR = 0;
1000                                 gint iRecord = 0;
1001                                 for (iRecord = 0; iRecord < iNbrRecords; iRecord++)
1002                                 {
1003                                         ti = proto_tree_add_text(tree, tvb, offset + iOffsetPMR, iSizePMR1, MQ_TEXT_PMR);
1004                                         mq_tree = proto_item_add_subtree(ti, ett_mq_pmr);
1005                                         if ((recFlags & MQ_PMRF_MSG_ID) != 0)
1006                                         {
1007                                                 proto_tree_add_item(mq_tree, hf_mq_pmr_msgid, tvb, offset + iOffsetPMR, 24, bLittleEndian);
1008                                                 iOffsetPMR += 24;
1009                                         }
1010                                         if ((recFlags & MQ_PMRF_CORREL_ID) != 0)
1011                                         {
1012                                                 proto_tree_add_item(mq_tree, hf_mq_pmr_correlid, tvb, offset + iOffsetPMR, 24, bLittleEndian);
1013                                                 iOffsetPMR += 24;
1014                                         }
1015                                         if ((recFlags & MQ_PMRF_GROUP_ID) != 0)
1016                                         {
1017                                                 proto_tree_add_item(mq_tree, hf_mq_pmr_groupid, tvb, offset + iOffsetPMR, 24, bLittleEndian);
1018                                                 iOffsetPMR += 24;
1019                                         }
1020                                         if ((recFlags & MQ_PMRF_FEEDBACK) != 0)
1021                                         {
1022                                                 proto_tree_add_item(mq_tree, hf_mq_pmr_feedback, tvb, offset + iOffsetPMR, 4, bLittleEndian);
1023                                                 iOffsetPMR += 4;
1024                                         }
1025                                         if ((recFlags & MQ_PMRF_ACCOUNTING_TOKEN) != 0)
1026                                         {
1027                                                 proto_tree_add_item(mq_tree, hf_mq_pmr_acttoken, tvb, offset + iOffsetPMR, 32, bLittleEndian);
1028                                                 iOffsetPMR += 32;
1029                                         }
1030                                 }
1031                         }
1032                 }
1033                 else iSizePMR = 0;
1034         }
1035         return iSizePMR;
1036 }
1037
1038 static gint
1039 dissect_mq_gmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset)
1040 {
1041         proto_tree      *mq_tree = NULL;
1042         proto_item      *ti = NULL;
1043         guint32 structId;
1044         gint iSizeGMO = 0;
1045
1046         if (tvb_length_remaining(tvb, offset) >= 4)
1047         {
1048                 structId = tvb_get_ntohl(tvb, offset);
1049                 if ((structId == MQ_STRUCTID_GMO || structId == MQ_STRUCTID_GMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
1050                 {
1051                         guint32 iVersionGMO = 0;
1052                         iVersionGMO = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
1053                         /* Compute length according to version */
1054                         switch (iVersionGMO)
1055                         {
1056                                 case 1: iSizeGMO = 72; break;
1057                                 case 2: iSizeGMO = 80; break;
1058                                 case 3: iSizeGMO = 100; break;
1059                         }
1060
1061                         if (iSizeGMO != 0 && tvb_length_remaining(tvb, offset) >= iSizeGMO)
1062                         {
1063                                 if (check_col(pinfo->cinfo, COL_INFO))
1064                                 {
1065                                         guint8* sQueue;
1066                                         sQueue = tvb_get_ephemeral_string(tvb, offset + 24, 48);
1067                                         if (strip_trailing_blanks(sQueue, 48) != 0)
1068                                         {
1069                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
1070                                         }
1071                                 }
1072
1073                                 if (tree)
1074                                 {
1075                                         ti = proto_tree_add_text(tree, tvb, offset, iSizeGMO, MQ_TEXT_GMO);
1076                                         mq_tree = proto_item_add_subtree(ti, ett_mq_gmo);
1077
1078                                         proto_tree_add_item(mq_tree, hf_mq_gmo_structid, tvb, offset, 4, FALSE);
1079                                         proto_tree_add_item(mq_tree, hf_mq_gmo_version, tvb, offset + 4, 4, bLittleEndian);
1080                                         proto_tree_add_item(mq_tree, hf_mq_gmo_options, tvb, offset + 8, 4, bLittleEndian);
1081                                         proto_tree_add_item(mq_tree, hf_mq_gmo_waitinterval, tvb, offset + 12, 4, bLittleEndian);
1082                                         proto_tree_add_item(mq_tree, hf_mq_gmo_signal1, tvb, offset + 16, 4, bLittleEndian);
1083                                         proto_tree_add_item(mq_tree, hf_mq_gmo_signal2, tvb, offset + 20, 4, bLittleEndian);
1084                                         proto_tree_add_item(mq_tree, hf_mq_gmo_resolvedqname, tvb, offset + 24, 48, FALSE);
1085
1086                                         if (iVersionGMO >= 2)
1087                                         {
1088                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_matchoptions, tvb, offset + 72, 4, FALSE);
1089                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_groupstatus, tvb, offset + 76, 1, FALSE);
1090                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_segmentstatus, tvb, offset + 77, 1, FALSE);
1091                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_segmentation, tvb, offset + 78, 1, FALSE);
1092                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_reserved, tvb, offset + 79, 1, FALSE);
1093                                         }
1094
1095                                         if (iVersionGMO >= 3)
1096                                         {
1097                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_msgtoken, tvb, offset + 80, 16, FALSE);
1098                                                 proto_tree_add_item(mq_tree, hf_mq_gmo_returnedlength, tvb, offset + 96, 4, bLittleEndian);
1099                                         }
1100                                 }
1101                         }
1102                 }
1103         }
1104         return iSizeGMO;
1105 }
1106
1107 static gint
1108 dissect_mq_pmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean bLittleEndian, gint offset, gint* iDistributionListSize)
1109 {
1110         proto_tree      *mq_tree = NULL;
1111         proto_item      *ti = NULL;
1112         guint32 structId;
1113         gint iSizePMO = 0;
1114
1115         if (tvb_length_remaining(tvb, offset) >= 4)
1116         {
1117                 structId = tvb_get_ntohl(tvb, offset);
1118                 if ((structId == MQ_STRUCTID_PMO || structId == MQ_STRUCTID_PMO_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
1119                 {
1120                         guint32 iVersionPMO = 0;
1121                         iVersionPMO = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
1122                         /* Compute length according to version */
1123                         switch (iVersionPMO)
1124                         {
1125                                 case 1: iSizePMO = 128; break;
1126                                 case 2: iSizePMO = 152;break;
1127                         }
1128
1129                         if (iSizePMO != 0 && tvb_length_remaining(tvb, offset) >= iSizePMO)
1130                         {
1131                                 gint iNbrRecords = 0;
1132                                 guint32 iRecFlags = 0;
1133                                 if (iVersionPMO >= 2)
1134                                 {
1135                                         iNbrRecords = tvb_get_guint32_endian(tvb, offset + 128, bLittleEndian);
1136                                         iRecFlags = tvb_get_guint32_endian(tvb, offset + 132, bLittleEndian);
1137                                 }
1138
1139                                 if (check_col(pinfo->cinfo, COL_INFO))
1140                                 {
1141                                         guint8* sQueue;
1142                                         sQueue = tvb_get_ephemeral_string(tvb, offset + 32, 48);
1143                                         if (strip_trailing_blanks(sQueue, 48) != 0)
1144                                         {
1145                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " Q=%s", sQueue);
1146                                         }
1147                                 }
1148
1149                                 if (tree)
1150                                 {
1151                                         ti = proto_tree_add_text(tree, tvb, offset, iSizePMO, MQ_TEXT_PMO);
1152                                         mq_tree = proto_item_add_subtree(ti, ett_mq_pmo);
1153                                         proto_tree_add_item(mq_tree, hf_mq_pmo_structid, tvb, offset, 4, FALSE);
1154                                         proto_tree_add_item(mq_tree, hf_mq_pmo_version, tvb, offset + 4, 4, bLittleEndian);
1155                                         proto_tree_add_item(mq_tree, hf_mq_pmo_options, tvb, offset + 8, 4, bLittleEndian);
1156                                         proto_tree_add_item(mq_tree, hf_mq_pmo_timeout, tvb, offset + 12, 4, bLittleEndian);
1157                                         proto_tree_add_item(mq_tree, hf_mq_pmo_context, tvb, offset + 16, 4, bLittleEndian);
1158                                         proto_tree_add_item(mq_tree, hf_mq_pmo_knowndestcount, tvb, offset + 20, 4, bLittleEndian);
1159                                         proto_tree_add_item(mq_tree, hf_mq_pmo_unknowndestcount, tvb, offset + 24, 4, bLittleEndian);
1160                                         proto_tree_add_item(mq_tree, hf_mq_pmo_invaliddestcount, tvb, offset + 28, 4, bLittleEndian);
1161                                         proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqname, tvb, offset + 32, 48, FALSE);
1162                                         proto_tree_add_item(mq_tree, hf_mq_pmo_resolvedqmgrname, tvb, offset + 80, 48, FALSE);
1163
1164                                         if (iVersionPMO >= 2)
1165                                         {
1166                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_recspresent, tvb, offset + 128, 4, bLittleEndian);
1167                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecfields, tvb, offset + 132, 4, bLittleEndian);
1168                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecoffset, tvb, offset + 136, 4, bLittleEndian);
1169                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_responserecoffset, tvb, offset + 140, 4, bLittleEndian);
1170                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_putmsgrecptr, tvb, offset + 144, 4, bLittleEndian);
1171                                                 proto_tree_add_item(mq_tree, hf_mq_pmo_responserecptr, tvb, offset + 148, 4, bLittleEndian);
1172                                         }
1173
1174                                 }
1175                                 if (iNbrRecords > 0)
1176                                 {
1177                                         gint iOffsetPMR = 0;
1178                                         gint iOffsetRR = 0;
1179                                         gint iSizePMRRR = 0;
1180
1181                                         *iDistributionListSize = iNbrRecords;
1182                                         iOffsetPMR = tvb_get_guint32_endian(tvb, offset + 136, bLittleEndian);
1183                                         iOffsetRR = tvb_get_guint32_endian(tvb, offset + 140, bLittleEndian);
1184                                         if ((iSizePMRRR = dissect_mq_pmr(tvb, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
1185                                                 iSizePMO += iSizePMRRR;
1186                                         if ((iSizePMRRR = dissect_mq_rr(tvb, tree, bLittleEndian, offset + iSizePMO, iNbrRecords, iOffsetRR)) != 0)
1187                                                 iSizePMO += iSizePMRRR;
1188                                 }
1189                         }
1190                 }
1191         }
1192         return iSizePMO;
1193 }
1194
1195 static gint
1196 dissect_mq_xid(tvbuff_t *tvb, proto_tree *tree, gboolean bLittleEndian, gint offset)
1197 {
1198         proto_tree      *mq_tree = NULL;
1199         proto_item      *ti = NULL;
1200         gint iSizeXid = 0;
1201         if (tvb_length_remaining(tvb, offset) >= 6)
1202         {
1203                 guint8 iXidLength = 0;
1204                 guint8 iBqLength = 0;
1205                 iXidLength = tvb_get_guint8(tvb, offset + 4);
1206                 iBqLength = tvb_get_guint8(tvb, offset + 5);
1207                 iSizeXid = 6 + iXidLength + iBqLength;
1208
1209                 if (tvb_length_remaining(tvb, offset) >= iSizeXid)
1210                 {
1211                         if (tree)
1212                         {
1213                                 ti = proto_tree_add_text(tree, tvb, offset, iSizeXid, MQ_TEXT_XID);
1214                                 mq_tree = proto_item_add_subtree(ti, ett_mq_xa_xid);
1215
1216                                 proto_tree_add_item(mq_tree, hf_mq_xa_xid_formatid, tvb, offset, 4, bLittleEndian);
1217                                 proto_tree_add_item(mq_tree, hf_mq_xa_xid_globalxid_length, tvb, offset + 4, 1, FALSE);
1218                                 proto_tree_add_item(mq_tree, hf_mq_xa_xid_brq_length, tvb, offset + 5, 1, FALSE);
1219                                 proto_tree_add_item(mq_tree, hf_mq_xa_xid_globalxid, tvb, offset + 6, iXidLength, FALSE);
1220                                 proto_tree_add_item(mq_tree, hf_mq_xa_xid_brq, tvb, offset + 6 + iXidLength, iBqLength, FALSE);
1221                         }
1222                         iSizeXid += (4 - (iSizeXid % 4)) % 4; /* Pad for alignment with 4 byte word boundary */
1223                         if (tvb_length_remaining(tvb, offset) < iSizeXid) iSizeXid = 0;
1224                 }
1225                 else iSizeXid = 0;
1226         }
1227         return iSizeXid;
1228 }
1229
1230 static void
1231 dissect_mq_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1232 {
1233         proto_tree      *mq_tree = NULL;
1234         proto_tree      *mqroot_tree = NULL;
1235         proto_item      *ti = NULL;
1236         gint offset = 0;
1237         guint32 structId = MQ_STRUCTID_NULL;
1238         guint8 opcode;
1239         guint32 iSegmentLength = 0;
1240         guint32 iSizePayload = 0;
1241         gint iSizeMD = 0;
1242         gboolean bLittleEndian = FALSE;
1243         gboolean bPayload = FALSE;
1244         gboolean bEBCDIC = FALSE;
1245         gint iDistributionListSize = 0;
1246         struct mq_msg_properties tMsgProps;
1247         static gint iPreviousFrameNumber = -1;
1248
1249         if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQ");
1250         if (check_col(pinfo->cinfo, COL_INFO))
1251         {
1252                 /* This is a trick to know whether this is the first PDU in this packet or not */
1253                 if (iPreviousFrameNumber != (gint) pinfo->fd->num)
1254                         col_clear(pinfo->cinfo, COL_INFO);
1255                 else
1256                         col_append_str(pinfo->cinfo, COL_INFO, " | ");
1257         }
1258         iPreviousFrameNumber = pinfo->fd->num;
1259         if (tvb_length(tvb) >= 4)
1260         {
1261                 structId = tvb_get_ntohl(tvb, offset);
1262                 if ((structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 28)
1263                 {
1264                         /* An MQ packet always starts with this structure*/
1265                         gint iSizeTSH = 28;
1266                         guint8 iControlFlags = 0;
1267                         if (structId == MQ_STRUCTID_TSH_EBCDIC) bEBCDIC = TRUE;
1268                         opcode = tvb_get_guint8(tvb, offset + 9);
1269                         bLittleEndian = (tvb_get_guint8(tvb, offset + 8) == MQ_LITTLE_ENDIAN ? TRUE : FALSE);
1270                         iSegmentLength = tvb_get_ntohl(tvb, offset + 4);
1271                         iControlFlags = tvb_get_guint8(tvb, offset + 10);
1272
1273                         if (check_col(pinfo->cinfo, COL_INFO))
1274                         {
1275                                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
1276                         }
1277
1278                         if (tree)
1279                         {
1280                                 ti = proto_tree_add_item(tree, proto_mq, tvb, offset, -1, FALSE);
1281                                 proto_item_append_text(ti, " (%s)", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
1282                                 if (bEBCDIC == TRUE) proto_item_append_text(ti, " (EBCDIC)");
1283                                 mqroot_tree = proto_item_add_subtree(ti, ett_mq);
1284
1285                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeTSH, MQ_TEXT_TSH);
1286                                 mq_tree = proto_item_add_subtree(ti, ett_mq_tsh);
1287
1288                                 proto_tree_add_item(mq_tree, hf_mq_tsh_structid, tvb, offset + 0, 4, FALSE);
1289                                 proto_tree_add_item(mq_tree, hf_mq_tsh_packetlength, tvb, offset + 4, 4, FALSE);
1290
1291                                 proto_tree_add_item(mq_tree, hf_mq_tsh_byteorder, tvb, offset + 8, 1, FALSE);
1292
1293                                 proto_tree_add_item(mq_tree, hf_mq_tsh_opcode, tvb, offset + 9, 1, FALSE);
1294
1295                                 /* Control flags */
1296                                 {
1297                                         proto_tree      *mq_tree_sub = NULL;
1298
1299                                         ti = proto_tree_add_item(mq_tree, hf_mq_tsh_controlflags, tvb, offset + 10, 1, FALSE);
1300                                         mq_tree_sub = proto_item_add_subtree(ti, ett_mq_tsh_tcf);
1301
1302                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_dlq, tvb, offset + 10, 1, iControlFlags);
1303                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_reqacc, tvb, offset + 10, 1, iControlFlags);
1304                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_last, tvb, offset + 10, 1, iControlFlags);
1305                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_first, tvb, offset + 10, 1, iControlFlags);
1306                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_closechann, tvb, offset + 10, 1, iControlFlags);
1307                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_reqclose, tvb, offset + 10, 1, iControlFlags);
1308                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_error, tvb, offset + 10, 1, iControlFlags);
1309                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_tsh_tcf_confirmreq, tvb, offset + 10, 1, iControlFlags);
1310                                 }
1311
1312                                 proto_tree_add_item(mq_tree, hf_mq_tsh_reserved, tvb, offset + 11, 1, FALSE);
1313                                 proto_tree_add_item(mq_tree, hf_mq_tsh_luwid, tvb, offset + 12, 8, FALSE);
1314                                 proto_tree_add_item(mq_tree, hf_mq_tsh_encoding, tvb, offset + 20, 4, bLittleEndian);
1315                                 proto_tree_add_item(mq_tree, hf_mq_tsh_ccsid, tvb, offset + 24, 2, bLittleEndian);
1316                                 proto_tree_add_item(mq_tree, hf_mq_tsh_padding, tvb, offset + 26, 2, FALSE);
1317                         }
1318                         offset += iSizeTSH;
1319
1320                         /* Now dissect the embedded structures */
1321                         if (tvb_length_remaining(tvb, offset) >= 4)
1322                         {
1323                                 structId = tvb_get_ntohl(tvb, offset);
1324                                 if (((iControlFlags & MQ_TCF_FIRST) != 0) || opcode < 0x80)
1325                                 {
1326                                         /* First MQ segment (opcodes below 0x80 never span several TSH) */
1327                                         gint iSizeAPI = 16;
1328                                         if (opcode >= 0x80 && opcode <= 0x9F && tvb_length_remaining(tvb, offset) >= 16)
1329                                         {
1330                                                 guint32 iReturnCode = 0;
1331                                                 iReturnCode = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
1332                                                 if (check_col(pinfo->cinfo, COL_INFO))
1333                                                 {
1334                                                         if (iReturnCode != 0)
1335                                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " [RC=%d]", iReturnCode);
1336                                                 }
1337
1338                                                 if (tree)
1339                                                 {
1340                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeAPI, MQ_TEXT_API);
1341                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_api);
1342
1343                                                         proto_tree_add_item(mq_tree, hf_mq_api_replylength, tvb, offset, 4, FALSE);
1344                                                         proto_tree_add_item(mq_tree, hf_mq_api_completioncode, tvb, offset + 4, 4, bLittleEndian);
1345                                                         proto_tree_add_item(mq_tree, hf_mq_api_reasoncode, tvb, offset + 8, 4, bLittleEndian);
1346                                                         proto_tree_add_item(mq_tree, hf_mq_api_objecthandle, tvb, offset + 12, 4, bLittleEndian);
1347                                                 }
1348                                                 offset += iSizeAPI;
1349                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1350                                         }
1351                                         if ((structId == MQ_STRUCTID_MSH || structId == MQ_STRUCTID_MSH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 20)
1352                                         {
1353                                                 gint iSizeMSH = 20;
1354                                                 iSizePayload = tvb_get_guint32_endian(tvb, offset + 16, bLittleEndian);
1355                                                 bPayload = TRUE;
1356                                                 if (tree)
1357                                                 {
1358                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMSH, MQ_TEXT_MSH);
1359                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_msh);
1360
1361                                                         proto_tree_add_item(mq_tree, hf_mq_msh_structid, tvb, offset + 0, 4, FALSE);
1362                                                         proto_tree_add_item(mq_tree, hf_mq_msh_seqnum, tvb, offset + 4, 4, bLittleEndian);
1363                                                         proto_tree_add_item(mq_tree, hf_mq_msh_datalength, tvb, offset + 8, 4, bLittleEndian);
1364                                                         proto_tree_add_item(mq_tree, hf_mq_msh_unknown1, tvb, offset + 12, 4, bLittleEndian);
1365                                                         proto_tree_add_item(mq_tree, hf_mq_msh_msglength, tvb, offset + 16, 4, bLittleEndian);
1366                                                 }
1367                                                 offset += iSizeMSH;
1368                                         }
1369                                         else if (opcode == MQ_TST_STATUS && tvb_length_remaining(tvb, offset) >= 8)
1370                                         {
1371                                                 /* Some status are 28 bytes long and some are 36 bytes long */
1372                                                 guint32 iStatus = 0;
1373                                                 gint iStatusLength = 0;
1374                                                 iStatus = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
1375                                                 iStatusLength = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
1376
1377                                                 if (tvb_length_remaining(tvb, offset) >= iStatusLength)
1378                                                 {
1379                                                         if (check_col(pinfo->cinfo, COL_INFO))
1380                                                         {
1381                                                                 if (iStatus != 0)
1382                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, ": Code=%s", val_to_str(iStatus, mq_status_vals, "Unknown (0x%08x)"));
1383                                                         }
1384                                                         if (tree)
1385                                                         {
1386                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, 8, MQ_TEXT_STAT);
1387                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_status);
1388
1389                                                                 proto_tree_add_item(mq_tree, hf_mq_status_length, tvb, offset, 4, bLittleEndian);
1390                                                                 proto_tree_add_item(mq_tree, hf_mq_status_code, tvb, offset + 4, 4, bLittleEndian);
1391
1392                                                                 if (iStatusLength >= 12)
1393                                                                         proto_tree_add_item(mq_tree, hf_mq_status_value, tvb, offset + 8, 4, bLittleEndian);
1394                                                         }
1395                                                         offset += iStatusLength;
1396                                                 }
1397                                         }
1398                                         else if (opcode == MQ_TST_PING && tvb_length_remaining(tvb, offset) > 4)
1399                                         {
1400                                                 if (tree)
1401                                                 {
1402                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_PING);
1403                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_ping);
1404
1405                                                         proto_tree_add_item(mq_tree, hf_mq_ping_length, tvb, offset, 4, bLittleEndian);
1406                                                         proto_tree_add_item(mq_tree, hf_mq_ping_buffer, tvb, offset + 4, -1, FALSE);
1407                                                 }
1408                                                 offset = tvb_length(tvb);
1409                                         }
1410                                         else if (opcode == MQ_TST_RESET && tvb_length_remaining(tvb, offset) >= 8)
1411                                         {
1412                                                 if (tree)
1413                                                 {
1414                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_RESET);
1415                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_reset);
1416
1417                                                         proto_tree_add_item(mq_tree, hf_mq_reset_length, tvb, offset, 4, bLittleEndian);
1418                                                         proto_tree_add_item(mq_tree, hf_mq_reset_seqnum, tvb, offset + 4, 4, bLittleEndian);
1419                                                 }
1420                                                 offset = tvb_length(tvb);
1421                                         }
1422                                         else if (opcode == MQ_TST_MQCONN && tvb_length_remaining(tvb, offset) > 0)
1423                                         {
1424                                                 gint iSizeCONN = 0;
1425                                                 /*iSizeCONN = ((iVersionID == 4 || iVersionID == 6) ? 120 : 112);*/ /* guess */
1426                                                 /* The iVersionID is available in the previous ID segment, we should keep a state
1427                                                  * Instead we rely on the segment length announced in the TSH */
1428                                                 /* The MQCONN structure is special because it does not start with a structid */
1429                                                 iSizeCONN = iSegmentLength - iSizeTSH - iSizeAPI;
1430                                                 if (iSizeCONN != 112 && iSizeCONN != 120) iSizeCONN = 0;
1431
1432                                                 if (iSizeCONN != 0 && tvb_length_remaining(tvb, offset) >= iSizeCONN)
1433                                                 {
1434                                                         if (check_col(pinfo->cinfo, COL_INFO))
1435                                                         {
1436                                                                 guint8* sApplicationName;
1437                                                                 guint8* sQueueManager;
1438                                                                 sApplicationName = tvb_get_ephemeral_string(tvb, offset + 48, 28);
1439                                                                 if (strip_trailing_blanks(sApplicationName, 28) != 0)
1440                                                                 {
1441                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, ": App=%s", sApplicationName);
1442                                                                 }
1443                                                                 sQueueManager = tvb_get_ephemeral_string(tvb, offset, 48);
1444                                                                 if (strip_trailing_blanks(sQueueManager, 48) != 0)
1445                                                                 {
1446                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
1447                                                                 }
1448                                                         }
1449
1450
1451                                                         if (tree)
1452                                                         {
1453                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeCONN, MQ_TEXT_CONN);
1454                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_conn);
1455
1456                                                                 proto_tree_add_item(mq_tree, hf_mq_conn_queuemanager, tvb, offset, 48, FALSE);
1457                                                                 proto_tree_add_item(mq_tree, hf_mq_conn_appname, tvb, offset + 48, 28, FALSE);
1458                                                                 proto_tree_add_item(mq_tree, hf_mq_conn_apptype, tvb, offset + 76, 4, bLittleEndian);
1459                                                                 proto_tree_add_item(mq_tree, hf_mq_conn_acttoken, tvb, offset + 80, 32, FALSE);
1460
1461                                                                 if (iSizeCONN >= 120)
1462                                                                 {
1463                                                                         proto_tree_add_item(mq_tree, hf_mq_conn_version, tvb, offset + 112, 4, bLittleEndian);
1464                                                                         proto_tree_add_item(mq_tree, hf_mq_conn_options, tvb, offset + 116, 4, bLittleEndian);
1465                                                                 }
1466                                                         }
1467                                                         offset += iSizeCONN;
1468                                                 }
1469                                         }
1470                                         else if ((opcode == MQ_TST_MQINQ || opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET) && tvb_length_remaining(tvb, offset) >= 12)
1471                                         {
1472                                                 /* The MQINQ/MQSET structure is special because it does not start with a structid */
1473                                                 gint iNbSelectors = 0;
1474                                                 gint iNbIntegers = 0;
1475                                                 gint iCharLen = 0;
1476                                                 gint iOffsetINQ = 0;
1477                                                 gint iSelector = 0;
1478
1479                                                 iNbSelectors = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
1480                                                 iNbIntegers = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
1481                                                 iCharLen = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
1482
1483                                                 if (tree)
1484                                                 {
1485                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, MQ_TEXT_INQ);
1486                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_inq);
1487
1488                                                         proto_tree_add_item(mq_tree, hf_mq_inq_nbsel, tvb, offset, 4, bLittleEndian);
1489                                                         proto_tree_add_item(mq_tree, hf_mq_inq_nbint, tvb, offset + 4, 4, bLittleEndian);
1490                                                         proto_tree_add_item(mq_tree, hf_mq_inq_charlen, tvb, offset + 8, 4, bLittleEndian);
1491                                                 }
1492                                                 iOffsetINQ = 12;
1493                                                 if (tvb_length_remaining(tvb, offset + iOffsetINQ) >= iNbSelectors * 4)
1494                                                 {
1495                                                         if (tree)
1496                                                         {
1497                                                                 for (iSelector = 0; iSelector < iNbSelectors; iSelector++)
1498                                                                 {
1499                                                                         proto_tree_add_item(mq_tree, hf_mq_inq_sel, tvb, offset + iOffsetINQ + iSelector * 4, 4, bLittleEndian);
1500                                                                 }
1501                                                         }
1502                                                         iOffsetINQ += iNbSelectors * 4;
1503                                                         if (opcode == MQ_TST_MQINQ_REPLY || opcode == MQ_TST_MQSET)
1504                                                         {
1505                                                                 gint iSizeINQValues = 0;
1506                                                                 iSizeINQValues = iNbIntegers * 4 + iCharLen;
1507                                                                 if (tvb_length_remaining(tvb, offset + iOffsetINQ) >= iSizeINQValues)
1508                                                                 {
1509                                                                         gint iInteger = 0;
1510                                                                         if (tree)
1511                                                                         {
1512                                                                                 for (iInteger = 0; iInteger < iNbIntegers; iInteger++)
1513                                                                                 {
1514                                                                                         proto_tree_add_item(mq_tree, hf_mq_inq_intvalue, tvb, offset + iOffsetINQ + iInteger * 4, 4, bLittleEndian);
1515                                                                                 }
1516                                                                         }
1517                                                                         iOffsetINQ += iNbIntegers * 4;
1518                                                                         if (iCharLen != 0)
1519                                                                         {
1520                                                                                 if (tree)
1521                                                                                 {
1522                                                                                         proto_tree_add_item(mq_tree, hf_mq_inq_charvalues, tvb, offset + iOffsetINQ, iCharLen, FALSE);
1523                                                                                 }
1524                                                                         }
1525                                                                 }
1526                                                         }
1527                                                 }
1528                                                 offset += tvb_length(tvb);
1529                                         }
1530                                         else if ((opcode == MQ_TST_SPI || opcode == MQ_TST_SPI_REPLY) && tvb_length_remaining(tvb, offset) >= 12)
1531                                         {
1532                                                 gint iOffsetSPI = 0;
1533                                                 guint32 iSpiVerb = 0;
1534
1535                                                 iSpiVerb = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
1536                                                 if (check_col(pinfo->cinfo, COL_INFO))
1537                                                 {
1538                                                         col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(iSpiVerb, mq_spi_verbs_vals, "Unknown (0x%08x)"));
1539                                                 }
1540
1541                                                 if (tree)
1542                                                 {
1543                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, 12, MQ_TEXT_SPI);
1544                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_spi);
1545
1546                                                         proto_tree_add_item(mq_tree, hf_mq_spi_verb, tvb, offset, 4, bLittleEndian);
1547                                                         proto_tree_add_item(mq_tree, hf_mq_spi_version, tvb, offset + 4, 4, bLittleEndian);
1548                                                         proto_tree_add_item(mq_tree, hf_mq_spi_length, tvb, offset + 8, 4, bLittleEndian);
1549                                                 }
1550
1551                                                 offset += 12;
1552                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1553                                                 if ((structId == MQ_STRUCTID_SPQU || structId == MQ_STRUCTID_SPAU_EBCDIC
1554                                                         || structId == MQ_STRUCTID_SPPU || structId == MQ_STRUCTID_SPPU_EBCDIC
1555                                                         || structId == MQ_STRUCTID_SPGU || structId == MQ_STRUCTID_SPGU_EBCDIC
1556                                                         || structId == MQ_STRUCTID_SPAU || structId == MQ_STRUCTID_SPAU_EBCDIC)
1557                                                         && tvb_length_remaining(tvb, offset) >= 12)
1558                                                 {
1559                                                         gint iSizeSPIMD = 0;
1560                                                         if (tree)
1561                                                         {
1562                                                                 guint8* sStructId;
1563                                                                 sStructId = tvb_get_ephemeral_string(tvb, offset, 4);
1564                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, 12, "%s", sStructId);
1565                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_spi_base);
1566
1567                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_base_structid, tvb, offset, 4, FALSE);
1568                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_base_version, tvb, offset + 4, 4, bLittleEndian);
1569                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_base_length, tvb, offset + 8, 4, bLittleEndian);
1570                                                         }
1571                                                         offset += 12;
1572                                                         structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1573
1574                                                         if ((iSizeSPIMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
1575                                                         {
1576                                                                 gint iSizeGMO = 0;
1577                                                                 gint iSizePMO = 0;
1578                                                                 offset += iSizeSPIMD;
1579
1580                                                                 if ((iSizeGMO = dissect_mq_gmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset)) != 0)
1581                                                                 {
1582                                                                         offset += iSizeGMO;
1583                                                                 }
1584                                                                 else if ((iSizePMO = dissect_mq_pmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iDistributionListSize)) != 0)
1585                                                                 {
1586                                                                         offset += iSizePMO;
1587                                                                 }
1588                                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1589                                                         }
1590
1591                                                         if ((structId == MQ_STRUCTID_SPQO || structId == MQ_STRUCTID_SPQO_EBCDIC
1592                                                                 || structId == MQ_STRUCTID_SPQI || structId == MQ_STRUCTID_SPQI_EBCDIC
1593                                                                 || structId == MQ_STRUCTID_SPPO || structId == MQ_STRUCTID_SPPO_EBCDIC
1594                                                                 || structId == MQ_STRUCTID_SPPI || structId == MQ_STRUCTID_SPPI_EBCDIC
1595                                                                 || structId == MQ_STRUCTID_SPGO || structId == MQ_STRUCTID_SPGO_EBCDIC
1596                                                                 || structId == MQ_STRUCTID_SPGI || structId == MQ_STRUCTID_SPGI_EBCDIC
1597                                                                 || structId == MQ_STRUCTID_SPAO || structId == MQ_STRUCTID_SPAO_EBCDIC
1598                                                                 || structId == MQ_STRUCTID_SPAI || structId == MQ_STRUCTID_SPAI_EBCDIC)
1599                                                                 && tvb_length_remaining(tvb, offset) >= 12)
1600                                                         {
1601                                                                 if (tree)
1602                                                                 {
1603                                                                         /* Dissect the common part of these structures */
1604                                                                         guint8* sStructId;
1605                                                                         sStructId = tvb_get_ephemeral_string(tvb, offset, 4);
1606                                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, -1, "%s", sStructId);
1607                                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_spi_base);
1608
1609                                                                         proto_tree_add_item(mq_tree, hf_mq_spi_base_structid, tvb, offset, 4, FALSE);
1610                                                                         proto_tree_add_item(mq_tree, hf_mq_spi_base_version, tvb, offset + 4, 4, bLittleEndian);
1611                                                                         proto_tree_add_item(mq_tree, hf_mq_spi_base_length, tvb, offset + 8, 4, bLittleEndian);
1612                                                                 }
1613
1614                                                                 if (structId == MQ_STRUCTID_SPQO && tvb_length_remaining(tvb, offset) >= 16)
1615                                                                 {
1616                                                                         if (tree)
1617                                                                         {
1618                                                                                 gint iVerbNumber = 0;
1619                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_nbverb, tvb, offset + 12, 4, bLittleEndian);
1620                                                                                 iVerbNumber = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
1621
1622                                                                                 if (tvb_length_remaining(tvb, offset) >= iVerbNumber * 20 + 16)
1623                                                                                 {
1624                                                                                         gint iVerb = 0;
1625                                                                                         iOffsetSPI = offset + 16;
1626                                                                                         for (iVerb = 0; iVerb < iVerbNumber; iVerb++)
1627                                                                                         {
1628                                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_verbid, tvb, iOffsetSPI, 4, bLittleEndian);
1629                                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_maxinoutversion, tvb, iOffsetSPI + 4, 4, bLittleEndian);
1630                                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_maxinversion, tvb, iOffsetSPI + 8, 4, bLittleEndian);
1631                                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_maxoutversion, tvb, iOffsetSPI + 12, 4, bLittleEndian);
1632                                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spqo_flags, tvb, iOffsetSPI + 16, 4, bLittleEndian);
1633                                                                                                 iOffsetSPI += 20;
1634                                                                                         }
1635                                                                                         offset += iVerbNumber * 20 + 16;
1636                                                                                 }
1637                                                                         }
1638                                                                 }
1639                                                                 else if (structId == MQ_STRUCTID_SPAI && tvb_length_remaining(tvb, offset) >= 136)
1640                                                                 {
1641                                                                         if (tree)
1642                                                                         {
1643                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spai_mode, tvb, offset + 12, 4, bLittleEndian);
1644                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spai_unknown1, tvb, offset + 16, 48, bLittleEndian);
1645                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spai_unknown2, tvb, offset + 64, 48, bLittleEndian);
1646                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spai_msgid, tvb, offset + 112, 24, bLittleEndian);
1647                                                                         }
1648                                                                         offset += 136;
1649                                                                 }
1650                                                                 else if (structId == MQ_STRUCTID_SPGI && tvb_length_remaining(tvb, offset) >= 24)
1651                                                                 {
1652                                                                         if (tree)
1653                                                                         {
1654                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spgi_batchsize, tvb, offset + 12, 4, bLittleEndian);
1655                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spgi_batchint, tvb, offset + 16, 4, bLittleEndian);
1656                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spgi_maxmsgsize, tvb, offset + 20, 4, bLittleEndian);
1657                                                                         }
1658                                                                         offset += 24;
1659                                                                 }
1660                                                                 else if ((structId == MQ_STRUCTID_SPGO || structId == MQ_STRUCTID_SPPI) && tvb_length_remaining(tvb, offset) >= 20)
1661                                                                 {
1662                                                                         if (tree)
1663                                                                         {
1664                                                                                 /* Options flags */
1665                                                                                 {
1666                                                                                         proto_tree      *mq_tree_sub = NULL;
1667                                                                                         gint iOptionsFlags;
1668
1669                                                                                         ti = proto_tree_add_item(mq_tree, hf_mq_spi_spgo_options, tvb, offset + 12, 4, bLittleEndian);
1670                                                                                         mq_tree_sub = proto_item_add_subtree(ti, ett_mq_spi_options);
1671                                                                                         iOptionsFlags = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
1672
1673                                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_deferred, tvb, offset + 12, 4, iOptionsFlags);
1674                                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_syncpoint, tvb, offset + 12, 4, iOptionsFlags);
1675                                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_spi_options_blank, tvb, offset + 12, 4, iOptionsFlags);
1676                                                                                 }
1677                                                                                 proto_tree_add_item(mq_tree, hf_mq_spi_spgo_size, tvb, offset + 16, 4, bLittleEndian);
1678                                                                         }
1679                                                                         iSizePayload = tvb_get_guint32_endian(tvb, offset + 16, bLittleEndian);
1680                                                                         offset += 20;
1681                                                                         bPayload = TRUE;
1682                                                                 }
1683                                                                 else
1684                                                                 {
1685                                                                         offset += 12;
1686                                                                 }
1687                                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1688                                                         }
1689                                                 }
1690                                         }
1691                                         else if ((opcode >= 0xA0 && opcode <= 0xB9) && tvb_length_remaining(tvb, offset) >= 16)
1692                                         {
1693                                                 /* The XA structures are special because they do not start with a structid */
1694                                                 if (tree)
1695                                                 {
1696                                                         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)"));
1697                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_xa);
1698
1699                                                         proto_tree_add_item(mq_tree, hf_mq_xa_length, tvb, offset, 4, FALSE);
1700                                                         proto_tree_add_item(mq_tree, hf_mq_xa_returnvalue, tvb, offset + 4, 4, bLittleEndian);
1701
1702                                                         /* Transaction Manager flags */
1703                                                         {
1704                                                                 proto_tree      *mq_tree_sub = NULL;
1705                                                                 guint32 iTMFlags;
1706
1707                                                                 ti = proto_tree_add_item(mq_tree, hf_mq_xa_tmflags, tvb, offset + 8, 4, bLittleEndian);
1708                                                                 mq_tree_sub = proto_item_add_subtree(ti, ett_mq_xa_tmflags);
1709                                                                 iTMFlags = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
1710
1711                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_onephase, tvb, offset + 8, 4, iTMFlags);
1712                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_fail, tvb, offset + 8, 4, iTMFlags);
1713                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_resume, tvb, offset + 8, 4, iTMFlags);
1714                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_success, tvb, offset + 8, 4, iTMFlags);
1715                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_suspend, tvb, offset + 8, 4, iTMFlags);
1716                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_startrscan, tvb, offset + 8, 4, iTMFlags);
1717                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_endrscan, tvb, offset + 8, 4, iTMFlags);
1718                                                                 proto_tree_add_boolean(mq_tree_sub, hf_mq_xa_tmflags_join, tvb, offset + 8, 4, iTMFlags);
1719                                                         }
1720
1721                                                         proto_tree_add_item(mq_tree, hf_mq_xa_rmid, tvb, offset + 12, 4, bLittleEndian);
1722                                                 }
1723                                                 offset += 16;
1724                                                 if (opcode == MQ_TST_XA_START || opcode == MQ_TST_XA_END || opcode == MQ_TST_XA_PREPARE
1725                                                         || opcode == MQ_TST_XA_COMMIT || opcode == MQ_TST_XA_ROLLBACK || opcode == MQ_TST_XA_FORGET
1726                                                         || opcode == MQ_TST_XA_COMPLETE)
1727                                                 {
1728                                                         gint iSizeXid = 0;
1729                                                         if ((iSizeXid = dissect_mq_xid(tvb, mqroot_tree, bLittleEndian, offset)) != 0)
1730                                                                 offset += iSizeXid;
1731                                                 }
1732                                                 else if ((opcode == MQ_TST_XA_OPEN || opcode == MQ_TST_XA_CLOSE)
1733                                                         && tvb_length_remaining(tvb, offset) >= 1)
1734                                                 {
1735                                                         guint8 iXAInfoLength = 0;
1736                                                         iXAInfoLength = tvb_get_guint8(tvb, offset);
1737                                                         if (tvb_length_remaining(tvb, offset) >= iXAInfoLength + 1)
1738                                                         {
1739                                                                 if (tree)
1740                                                                 {
1741                                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, iXAInfoLength + 1, MQ_TEXT_XINF);
1742                                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_xa_info);
1743
1744                                                                         proto_tree_add_item(mq_tree, hf_mq_xa_xainfo_length, tvb, offset, 1, FALSE);
1745                                                                         proto_tree_add_item(mq_tree, hf_mq_xa_xainfo_value, tvb, offset + 1, iXAInfoLength, FALSE);
1746                                                                 }
1747                                                         }
1748                                                         offset += 1 + iXAInfoLength;
1749                                                 }
1750                                                 else if ((opcode == MQ_TST_XA_RECOVER || opcode == MQ_TST_XA_RECOVER_REPLY)
1751                                                         && tvb_length_remaining(tvb, offset) >= 4)
1752                                                 {
1753                                                         gint iNbXid = 0;
1754                                                         iNbXid = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
1755                                                         if (tree)
1756                                                         {
1757                                                                 proto_tree_add_item(mq_tree, hf_mq_xa_count, tvb, offset, 4, bLittleEndian);
1758                                                         }
1759                                                         offset += 4;
1760                                                         if (opcode == MQ_TST_XA_RECOVER_REPLY)
1761                                                         {
1762                                                                 gint iXid = 0;
1763                                                                 for (iXid = 0; iXid < iNbXid; iXid++)
1764                                                                 {
1765                                                                         gint iSizeXid = 0;
1766                                                                         if ((iSizeXid = dissect_mq_xid(tvb, mqroot_tree, bLittleEndian, offset)) != 0)
1767                                                                                 offset += iSizeXid;
1768                                                                         else
1769                                                                                 break;
1770                                                                 }
1771                                                         }
1772                                                 }
1773                                         }
1774                                         else if ((structId == MQ_STRUCTID_ID || structId == MQ_STRUCTID_ID_EBCDIC) && tvb_length_remaining(tvb, offset) >= 5)
1775                                         {
1776                                                 guint8 iVersionID = 0;
1777                                                 gint iSizeID = 0;
1778                                                 iVersionID = tvb_get_guint8(tvb, offset + 4);
1779                                                 iSizeID = (iVersionID < 4 ? 44 : 104); /* guess */
1780                                                 /* actually 102 but must be aligned to multiple of 4 */
1781
1782                                                 if (iSizeID != 0 && tvb_length_remaining(tvb, offset) >= iSizeID)
1783                                                 {
1784                                                         if (check_col(pinfo->cinfo, COL_INFO))
1785                                                         {
1786                                                                 guint8* sChannel;
1787                                                                 sChannel = tvb_get_ephemeral_string(tvb, offset + 24, 20);
1788                                                                 if (strip_trailing_blanks(sChannel, 20) != 0)
1789                                                                 {
1790                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, ": CHL=%s", sChannel);
1791                                                                 }
1792                                                         }
1793
1794                                                         if (tree)
1795                                                         {
1796                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeID, MQ_TEXT_ID);
1797                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_id);
1798
1799                                                                 proto_tree_add_item(mq_tree, hf_mq_id_structid, tvb, offset, 4, FALSE);
1800                                                                 proto_tree_add_item(mq_tree, hf_mq_id_level, tvb, offset + 4, 1, FALSE);
1801
1802                                                                 /* ID flags */
1803                                                                 {
1804                                                                         proto_tree      *mq_tree_sub = NULL;
1805                                                                         guint8 iIDFlags;
1806
1807                                                                         ti = proto_tree_add_item(mq_tree, hf_mq_id_flags, tvb, offset + 5, 1, FALSE);
1808                                                                         mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_icf);
1809                                                                         iIDFlags = tvb_get_guint8(tvb, offset + 5);
1810
1811                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_runtime, tvb, offset + 5, 1, iIDFlags);
1812                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_svrsec, tvb, offset + 5, 1, iIDFlags);
1813                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_mqreq, tvb, offset + 5, 1, iIDFlags);
1814                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_splitmsg, tvb, offset + 5, 1, iIDFlags);
1815                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_convcap, tvb, offset + 5, 1, iIDFlags);
1816                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_icf_msgseq, tvb, offset + 5, 1, iIDFlags);
1817                                                                 }
1818
1819                                                                 proto_tree_add_item(mq_tree, hf_mq_id_unknown2, tvb, offset + 6, 1, FALSE);
1820
1821                                                                 /* Error flags */
1822                                                                 {
1823                                                                         proto_tree      *mq_tree_sub = NULL;
1824                                                                         guint8 iErrorFlags;
1825
1826                                                                         ti = proto_tree_add_item(mq_tree, hf_mq_id_ieflags, tvb, offset + 7, 1, FALSE);
1827                                                                         mq_tree_sub = proto_item_add_subtree(ti, ett_mq_id_ief);
1828                                                                         iErrorFlags = tvb_get_guint8(tvb, offset + 7);
1829
1830                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_hbint, tvb, offset + 7, 1, iErrorFlags);
1831                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_seqwrap, tvb, offset + 7, 1, iErrorFlags);
1832                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgpb, tvb, offset + 7, 1, iErrorFlags);
1833                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxmsgsz, tvb, offset + 7, 1, iErrorFlags);
1834                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_fap, tvb, offset + 7, 1, iErrorFlags);
1835                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_mxtrsz, tvb, offset + 7, 1, iErrorFlags);
1836                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_enc, tvb, offset + 7, 1, iErrorFlags);
1837                                                                         proto_tree_add_boolean(mq_tree_sub, hf_mq_id_ief_ccsid, tvb, offset + 7, 1, iErrorFlags);
1838                                                                 }
1839
1840                                                                 proto_tree_add_item(mq_tree, hf_mq_id_unknown4, tvb, offset + 8, 2, FALSE);
1841                                                                 proto_tree_add_item(mq_tree, hf_mq_id_maxmsgperbatch, tvb, offset + 10, 2, bLittleEndian);
1842                                                                 proto_tree_add_item(mq_tree, hf_mq_id_maxtransmissionsize, tvb, offset + 12, 4, bLittleEndian);
1843                                                                 proto_tree_add_item(mq_tree, hf_mq_id_maxmsgsize, tvb, offset + 16, 4, bLittleEndian);
1844                                                                 proto_tree_add_item(mq_tree, hf_mq_id_sequencewrapvalue, tvb, offset + 20, 4, bLittleEndian);
1845                                                                 proto_tree_add_item(mq_tree, hf_mq_id_channel, tvb, offset + 24, 20, FALSE);
1846                                                         }
1847
1848                                                         if (iVersionID >= 4)
1849                                                         {
1850                                                                 if (check_col(pinfo->cinfo, COL_INFO))
1851                                                                 {
1852                                                                         guint8* sQueueManager;
1853                                                                         sQueueManager = tvb_get_ephemeral_string(tvb, offset + 48, 48);
1854                                                                         if (strip_trailing_blanks(sQueueManager,48) != 0)
1855                                                                         {
1856                                                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " QM=%s", sQueueManager);
1857                                                                         }
1858                                                                 }
1859
1860                                                                 if (tree)
1861                                                                 {
1862                                                                         proto_tree_add_item(mq_tree, hf_mq_id_capflags, tvb, offset + 44, 1, FALSE);
1863                                                                         proto_tree_add_item(mq_tree, hf_mq_id_unknown5, tvb, offset + 45, 1, FALSE);
1864                                                                         proto_tree_add_item(mq_tree, hf_mq_id_ccsid, tvb, offset + 46, 2, bLittleEndian);
1865                                                                         proto_tree_add_item(mq_tree, hf_mq_id_queuemanager, tvb, offset + 48, 48, FALSE);
1866                                                                         proto_tree_add_item(mq_tree, hf_mq_id_heartbeatinterval, tvb, offset + 96, 4, bLittleEndian);
1867                                                                 }
1868
1869                                                         }
1870                                                         offset += iSizeID;
1871                                                 }
1872                                         }
1873                                         else if ((structId == MQ_STRUCTID_UID || structId == MQ_STRUCTID_UID_EBCDIC) && tvb_length_remaining(tvb, offset) > 0)
1874                                         {
1875                                                 gint iSizeUID = 0;
1876                                                 /* iSizeUID = (iVersionID < 5 ? 28 : 132);  guess */
1877                                                 /* The iVersionID is available in the previous ID segment, we should keep a state *
1878                                                  * Instead we rely on the segment length announced in the TSH */
1879                                                 iSizeUID = iSegmentLength - iSizeTSH;
1880                                                 if (iSizeUID != 28 && iSizeUID != 132) iSizeUID = 0;
1881
1882                                                 if (iSizeUID != 0 && tvb_length_remaining(tvb, offset) >= iSizeUID)
1883                                                 {
1884                                                         if (check_col(pinfo->cinfo, COL_INFO))
1885                                                         {
1886                                                                 guint8* sUserId;
1887                                                                 sUserId = tvb_get_ephemeral_string(tvb, offset + 4, 12);
1888                                                                 if (strip_trailing_blanks(sUserId, 12) != 0)
1889                                                                 {
1890                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, ": User=%s", sUserId);
1891                                                                 }
1892                                                         }
1893
1894                                                         if (tree)
1895                                                         {
1896                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeUID, MQ_TEXT_UID);
1897                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_uid);
1898
1899                                                                 proto_tree_add_item(mq_tree, hf_mq_uid_structid, tvb, offset, 4, FALSE);
1900                                                                 proto_tree_add_item(mq_tree, hf_mq_uid_userid, tvb, offset + 4, 12, FALSE);
1901                                                                 proto_tree_add_item(mq_tree, hf_mq_uid_password, tvb, offset + 16, 12, FALSE);
1902                                                         }
1903
1904                                                         if (iSizeUID == 132)
1905                                                         {
1906                                                                 if (tree)
1907                                                                 {
1908                                                                         proto_tree_add_item(mq_tree, hf_mq_uid_longuserid, tvb, offset + 28, 64, FALSE);
1909                                                                         proto_tree_add_item(mq_tree, hf_mq_uid_securityid, tvb, offset + 92, 40, FALSE);
1910                                                                 }
1911                                                         }
1912                                                         offset += iSizeUID;
1913                                                 }
1914                                         }
1915                                         if ((structId == MQ_STRUCTID_OD || structId == MQ_STRUCTID_OD_EBCDIC) && tvb_length_remaining(tvb, offset) >= 8)
1916                                         {
1917                                                 /* The OD struct can be present in several messages at different levels */
1918                                                 gint iSizeOD = 0;
1919                                                 guint32 iVersionOD = 0;
1920                                                 iVersionOD = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
1921                                                 /* Compute length according to version */
1922                                                 switch (iVersionOD)
1923                                                 {
1924                                                         case 1: iSizeOD = 168; break;
1925                                                         case 2: iSizeOD = 200; break;
1926                                                         case 3: iSizeOD = 336; break;
1927                                                 }
1928
1929                                                 if (iSizeOD != 0 && tvb_length_remaining(tvb, offset) >= iSizeOD)
1930                                                 {
1931                                                         gint iNbrRecords = 0;
1932                                                         if (iVersionOD >= 2)
1933                                                                 iNbrRecords = tvb_get_guint32_endian(tvb, offset + 168, bLittleEndian);
1934
1935                                                         if (check_col(pinfo->cinfo, COL_INFO))
1936                                                         {
1937                                                                 guint8* sQueue;
1938                                                                 sQueue = tvb_get_ephemeral_string(tvb, offset + 12, 48);
1939                                                                 if (strip_trailing_blanks(sQueue,48) != 0)
1940                                                                 {
1941                                                                         col_append_fstr(pinfo->cinfo, COL_INFO, " Obj=%s", sQueue);
1942                                                                 }
1943                                                         }
1944
1945                                                         if (tree)
1946                                                         {
1947                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeOD, MQ_TEXT_OD);
1948                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_od);
1949
1950                                                                 proto_tree_add_item(mq_tree, hf_mq_od_structid, tvb, offset, 4, FALSE);
1951                                                                 proto_tree_add_item(mq_tree, hf_mq_od_version, tvb, offset + 4, 4, bLittleEndian);
1952                                                                 proto_tree_add_item(mq_tree, hf_mq_od_objecttype, tvb, offset + 8, 4, bLittleEndian);
1953                                                                 proto_tree_add_item(mq_tree, hf_mq_od_objectname, tvb, offset + 12, 48, FALSE);
1954                                                                 proto_tree_add_item(mq_tree, hf_mq_od_objectqmgrname, tvb, offset + 60, 48, FALSE);
1955                                                                 proto_tree_add_item(mq_tree, hf_mq_od_dynamicqname, tvb, offset + 108, 48, FALSE);
1956                                                                 proto_tree_add_item(mq_tree, hf_mq_od_alternateuserid, tvb, offset + 156, 12, FALSE);
1957
1958                                                                 if (iVersionOD >= 2)
1959                                                                 {
1960                                                                         proto_tree_add_item(mq_tree, hf_mq_od_recspresent, tvb, offset + 168, 4, bLittleEndian);
1961                                                                         proto_tree_add_item(mq_tree, hf_mq_od_knowndestcount, tvb, offset + 172, 4, bLittleEndian);
1962                                                                         proto_tree_add_item(mq_tree, hf_mq_od_unknowndestcount, tvb, offset + 176, 4, bLittleEndian);
1963                                                                         proto_tree_add_item(mq_tree, hf_mq_od_invaliddestcount, tvb, offset + 180, 4, bLittleEndian);
1964                                                                         proto_tree_add_item(mq_tree, hf_mq_od_objectrecoffset, tvb, offset + 184, 4, bLittleEndian);
1965                                                                         proto_tree_add_item(mq_tree, hf_mq_od_responserecoffset, tvb, offset + 188, 4, bLittleEndian);
1966                                                                         proto_tree_add_item(mq_tree, hf_mq_od_objectrecptr, tvb, offset + 192, 4, bLittleEndian);
1967                                                                         proto_tree_add_item(mq_tree, hf_mq_od_responserecptr, tvb, offset + 196, 4, bLittleEndian);
1968                                                                 }
1969
1970                                                                 if (iVersionOD >= 3)
1971                                                                 {
1972                                                                         proto_tree_add_item(mq_tree, hf_mq_od_alternatesecurityid, tvb, offset + 200, 40, FALSE);
1973                                                                         proto_tree_add_item(mq_tree, hf_mq_od_resolvedqname, tvb, offset + 240, 48, FALSE);
1974                                                                         proto_tree_add_item(mq_tree, hf_mq_od_resolvedqmgrname, tvb, offset + 288, 48, FALSE);
1975                                                                 }
1976
1977                                                         }
1978                                                         offset += iSizeOD;
1979
1980                                                         if (iNbrRecords > 0)
1981                                                         {
1982                                                                 gint iOffsetOR = 0;
1983                                                                 gint iOffsetRR = 0;
1984                                                                 gint iSizeORRR = 0;
1985
1986                                                                 iDistributionListSize = iNbrRecords;
1987                                                                 iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 184, bLittleEndian);
1988                                                                 iOffsetRR = tvb_get_guint32_endian(tvb, offset - iSizeOD + 188, bLittleEndian);
1989                                                                 if ((iSizeORRR = dissect_mq_or(tvb, mqroot_tree, offset, iNbrRecords, iOffsetOR)) != 0)
1990                                                                         offset += iSizeORRR;
1991                                                                 if ((iSizeORRR = dissect_mq_rr(tvb, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetRR)) != 0)
1992                                                                         offset += iSizeORRR;
1993                                                         }
1994                                                 }
1995                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
1996                                         }
1997                                         if ((opcode == MQ_TST_MQOPEN || opcode == MQ_TST_MQCLOSE
1998                                                 || opcode == MQ_TST_MQOPEN_REPLY || opcode == MQ_TST_MQCLOSE_REPLY)
1999                                                 && tvb_length_remaining(tvb, offset) >= 4)
2000                                         {
2001                                                 if (tree)
2002                                                 {
2003                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_OPEN);
2004                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_open);
2005                                                         proto_tree_add_item(mq_tree, hf_mq_open_options, tvb, offset, 4, bLittleEndian);
2006                                                 }
2007                                                 offset += 4;
2008                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2009                                         }
2010                                         if ((iSizeMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
2011                                         {
2012                                                 gint iSizeGMO = 0;
2013                                                 gint iSizePMO = 0;
2014                                                 offset += iSizeMD;
2015
2016                                                 if ((iSizeGMO = dissect_mq_gmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset)) != 0)
2017                                                 {
2018                                                         offset += iSizeGMO;
2019                                                         bPayload = TRUE;
2020                                                 }
2021                                                 else if ((iSizePMO = dissect_mq_pmo(tvb, pinfo, mqroot_tree, bLittleEndian, offset, &iDistributionListSize)) != 0)
2022                                                 {
2023                                                         offset += iSizePMO;
2024                                                         bPayload = TRUE;
2025                                                 }
2026                                                 if (tvb_length_remaining(tvb, offset) >= 4)
2027                                                 {
2028                                                         if (bPayload == TRUE)
2029                                                         {
2030                                                                 iSizePayload = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
2031                                                                 if (tree)
2032                                                                 {
2033                                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, 4, MQ_TEXT_PUT);
2034                                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_put);
2035                                                                         proto_tree_add_item(mq_tree, hf_mq_put_length, tvb, offset, 4, bLittleEndian);
2036                                                                 }
2037                                                                 offset += 4;
2038                                                         }
2039                                                 }
2040                                         }
2041                                         if (iDistributionListSize > 0)
2042                                         {
2043                                                 if (check_col(pinfo->cinfo, COL_INFO))
2044                                                         col_append_fstr(pinfo->cinfo, COL_INFO, " (Distribution List, Size=%d)", iDistributionListSize);
2045                                         }
2046                                         if (bPayload == TRUE)
2047                                         {
2048                                                 if (iSizePayload != 0 && tvb_length_remaining(tvb, offset) > 0)
2049                                                 {
2050                                                         /* For the following header structures, each structure has a "format" field
2051                                                            which announces the type of the following structure.  For dissection we
2052                                                            do not use it and rely on the structid instead. */
2053                                                         guint32 iHeadersLength = 0;
2054                                                         if (tvb_length_remaining(tvb, offset) >= 4)
2055                                                         {
2056                                                                 gint iSizeMD = 0;
2057                                                                 structId = tvb_get_ntohl(tvb, offset);
2058
2059                                                                 if ((structId == MQ_STRUCTID_XQH || structId == MQ_STRUCTID_XQH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 104)
2060                                                                 {
2061                                                                         /* if MD.format == MQXMIT */
2062                                                                         gint iSizeXQH = 104;
2063                                                                         if (tree)
2064                                                                         {
2065                                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeXQH, MQ_TEXT_XQH);
2066                                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_xqh);
2067
2068                                                                                 proto_tree_add_item(mq_tree, hf_mq_xqh_structid, tvb, offset, 4, FALSE);
2069                                                                                 proto_tree_add_item(mq_tree, hf_mq_xqh_version, tvb, offset + 4, 4, bLittleEndian);
2070                                                                                 proto_tree_add_item(mq_tree, hf_mq_xqh_remoteq, tvb, offset + 8, 48, FALSE);
2071                                                                                 proto_tree_add_item(mq_tree, hf_mq_xqh_remoteqmgr, tvb, offset + 56, 48, FALSE);
2072                                                                         }
2073                                                                         offset += iSizeXQH;
2074                                                                         iHeadersLength += iSizeXQH;
2075
2076                                                                         if ((iSizeMD = dissect_mq_md(tvb, mqroot_tree, bLittleEndian, offset, &tMsgProps)) != 0)
2077                                                                         {
2078                                                                                 offset += iSizeMD;
2079                                                                                 iHeadersLength += iSizeMD;
2080                                                                         }
2081
2082                                                                         structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2083                                                                 }
2084                                                                 if ((structId == MQ_STRUCTID_DH || structId == MQ_STRUCTID_DH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 48)
2085                                                                 {
2086                                                                         /* if MD.format == MQHDIST */
2087                                                                         gint iSizeDH = 48;
2088                                                                         gint iNbrRecords = 0;
2089                                                                         guint32 iRecFlags = 0;
2090
2091                                                                         iNbrRecords = tvb_get_guint32_endian(tvb, offset + 36, bLittleEndian);
2092                                                                         iRecFlags = tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian);
2093                                                                         tMsgProps.iOffsetEncoding = offset + 12;
2094                                                                         tMsgProps.iOffsetCcsid    = offset + 16;
2095                                                                         tMsgProps.iOffsetFormat   = offset + 20;
2096
2097                                                                         if (tree)
2098                                                                         {
2099                                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDH, MQ_TEXT_DH);
2100                                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_dh);
2101
2102                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
2103                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
2104                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
2105                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
2106                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
2107                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
2108                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
2109                                                                                 proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecfields, tvb, offset + 32, 4, bLittleEndian);
2110                                                                                 proto_tree_add_item(mq_tree, hf_mq_dh_recspresent, tvb, offset + 36, 4, bLittleEndian);
2111                                                                                 proto_tree_add_item(mq_tree, hf_mq_dh_objectrecoffset , tvb, offset + 40, 4, bLittleEndian);
2112                                                                                 proto_tree_add_item(mq_tree, hf_mq_dh_putmsgrecoffset, tvb, offset + 44, 4, bLittleEndian);
2113                                                                         }
2114                                                                         offset += iSizeDH;
2115                                                                         iHeadersLength += iSizeDH;
2116
2117                                                                         if (iNbrRecords > 0)
2118                                                                         {
2119                                                                                 gint iOffsetOR = 0;
2120                                                                                 gint iOffsetPMR = 0;
2121                                                                                 gint iSizeORPMR = 0;
2122
2123                                                                                 iOffsetOR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 40, bLittleEndian);
2124                                                                                 iOffsetPMR = tvb_get_guint32_endian(tvb, offset - iSizeDH + 44, bLittleEndian);
2125                                                                                 if ((iSizeORPMR = dissect_mq_or(tvb, mqroot_tree, offset, iNbrRecords, iOffsetOR)) != 0)
2126                                                                                 {
2127                                                                                         offset += iSizeORPMR;
2128                                                                                         iHeadersLength += iSizeORPMR;
2129                                                                                 }
2130                                                                                 if ((iSizeORPMR = dissect_mq_pmr(tvb, mqroot_tree, bLittleEndian, offset, iNbrRecords, iOffsetPMR, iRecFlags)) != 0)
2131                                                                                 {
2132                                                                                         offset += iSizeORPMR;
2133                                                                                         iHeadersLength += iSizeORPMR;
2134                                                                                 }
2135                                                                         }
2136
2137                                                                         structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2138                                                                 }
2139                                                                 if ((structId == MQ_STRUCTID_DLH || structId == MQ_STRUCTID_DLH_EBCDIC) && tvb_length_remaining(tvb, offset) >= 172)
2140                                                                 {
2141                                                                         /* if MD.format == MQDEAD */
2142                                                                         gint iSizeDLH = 172;
2143                                                                         tMsgProps.iOffsetEncoding = offset + 108;
2144                                                                         tMsgProps.iOffsetCcsid    = offset + 112;
2145                                                                         tMsgProps.iOffsetFormat   = offset + 116;
2146                                                                         if (tree)
2147                                                                         {
2148                                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeDLH, MQ_TEXT_DLH);
2149                                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_dlh);
2150
2151                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_structid, tvb, offset, 4, FALSE);
2152                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_version, tvb, offset + 4, 4, bLittleEndian);
2153                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_reason, tvb, offset + 8, 4, bLittleEndian);
2154                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_destq, tvb, offset + 12, 48, FALSE);
2155                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_destqmgr, tvb, offset + 60, 48, FALSE);
2156                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_encoding, tvb, offset + 108, 4, bLittleEndian);
2157                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_ccsid, tvb, offset + 112, 4, bLittleEndian);
2158                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_format, tvb, offset + 116, 8, FALSE);
2159                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_putappltype, tvb, offset + 124, 4, bLittleEndian);
2160                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_putapplname, tvb, offset + 128, 28, FALSE);
2161                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_putdate, tvb, offset + 156, 8, FALSE);
2162                                                                                 proto_tree_add_item(mq_tree, hf_mq_dlh_puttime, tvb, offset + 164, 8, FALSE);
2163                                                                         }
2164                                                                         offset += iSizeDLH;
2165                                                                         iHeadersLength += iSizeDLH;
2166                                                                         structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2167                                                                 }
2168                                                                 if ((structId == MQ_STRUCTID_MDE || structId == MQ_STRUCTID_MDE_EBCDIC) && tvb_length_remaining(tvb, offset) >= 72)
2169                                                                 {
2170                                                                         /* if MD.format == MQHMDE */
2171                                                                         gint iSizeMDE = 72;
2172                                                                         tMsgProps.iOffsetEncoding = offset + 12;
2173                                                                         tMsgProps.iOffsetCcsid    = offset + 16;
2174                                                                         tMsgProps.iOffsetFormat   = offset + 20;
2175                                                                         if (tree)
2176                                                                         {
2177                                                                                 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMDE, MQ_TEXT_MDE);
2178                                                                                 mq_tree = proto_item_add_subtree(ti, ett_mq_mde);
2179
2180                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
2181                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
2182                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
2183                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
2184                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
2185                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
2186                                                                                 proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
2187                                                                                 proto_tree_add_item(mq_tree, hf_mq_md_groupid, tvb, offset + 32, 24, FALSE);
2188                                                                                 proto_tree_add_item(mq_tree, hf_mq_md_msgseqnumber, tvb, offset + 56, 4, bLittleEndian);
2189                                                                                 proto_tree_add_item(mq_tree, hf_mq_md_offset, tvb, offset + 60, 4, bLittleEndian);
2190                                                                                 proto_tree_add_item(mq_tree, hf_mq_md_msgflags, tvb, offset + 64, 4, bLittleEndian);
2191                                                                                 proto_tree_add_item(mq_tree, hf_mq_md_originallength, tvb, offset + 68, 4, bLittleEndian);
2192                                                                         }
2193                                                                         offset += iSizeMDE;
2194                                                                         iHeadersLength += iSizeMDE;
2195                                                                         structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2196                                                                 }
2197                                                                 if ((structId == MQ_STRUCTID_CIH || structId == MQ_STRUCTID_CIH_EBCDIC
2198                                                                         || structId == MQ_STRUCTID_IIH || structId == MQ_STRUCTID_IIH_EBCDIC
2199                                                                         || structId == MQ_STRUCTID_RFH || structId == MQ_STRUCTID_RFH_EBCDIC
2200                                                                         || structId == MQ_STRUCTID_RMH || structId == MQ_STRUCTID_RMH_EBCDIC
2201                                                                         || structId == MQ_STRUCTID_WIH || structId == MQ_STRUCTID_WIH_EBCDIC)
2202                                                                                 && tvb_length_remaining(tvb, offset) >= 12)
2203                                                                 {
2204                                                                         /* Dissect the generic part of the other pre-defined headers */
2205                                                                         /* We assume that only one such header is present */
2206                                                                         gint iSizeHeader = 0;
2207                                                                         iSizeHeader = (gint) tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
2208                   /* XXX - 32 is inferred from the code below.  What's the
2209                    * correct minimum? */
2210                   if (iSizeHeader <= 32)
2211                         THROW(ReportedBoundsError);
2212
2213                                                                         if (tvb_length_remaining(tvb, offset) >= iSizeHeader)
2214                                                                         {
2215                                                                                 tMsgProps.iOffsetEncoding = offset + 12;
2216                                                                                 tMsgProps.iOffsetCcsid    = offset + 16;
2217                                                                                 tMsgProps.iOffsetFormat   = offset + 20;
2218                                                                                 if (tree)
2219                                                                                 {
2220                                                                                         ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeHeader, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
2221                                                                                         mq_tree = proto_item_add_subtree(ti, ett_mq_head);
2222
2223                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_structid, tvb, offset, 4, FALSE);
2224                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_version, tvb, offset + 4, 4, bLittleEndian);
2225                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_length, tvb, offset + 8, 4, bLittleEndian);
2226                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_encoding, tvb, offset + 12, 4, bLittleEndian);
2227                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_ccsid, tvb, offset + 16, 4, bLittleEndian);
2228                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_format, tvb, offset + 20, 8, FALSE);
2229                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_flags, tvb, offset + 28, 4, bLittleEndian);
2230                                                                                         proto_tree_add_item(mq_tree, hf_mq_head_struct, tvb, offset + 32, iSizeHeader - 32, bLittleEndian);
2231
2232                                                                                 }
2233                                                                                 offset += iSizeHeader;
2234                                                                                 iHeadersLength += iSizeHeader;
2235                                                                                 structId = (tvb_length_remaining(tvb, offset) >= 4) ? tvb_get_ntohl(tvb, offset) : MQ_STRUCTID_NULL;
2236                                                                         }
2237                                                                 }
2238                                                         }
2239
2240                                                         if (tMsgProps.iOffsetFormat != 0)
2241                                                         {
2242                                                                         guint8* sFormat = NULL;
2243                                                                         sFormat = tvb_get_ephemeral_string(tvb, tMsgProps.iOffsetFormat, 8);
2244                                                                         if (strip_trailing_blanks(sFormat, 8) == 0)     sFormat = (guint8*)g_strdup("MQNONE");
2245                                                                         if (check_col(pinfo->cinfo, COL_INFO))
2246                                                                         {
2247                                                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " Fmt=%s", sFormat);
2248                                                                         }
2249                                                                         if (tree)
2250                                                                         {
2251                                                                                 proto_tree_add_string_hidden(tree, hf_mq_md_hidden_lastformat, tvb, tMsgProps.iOffsetFormat, 8, (const char*)sFormat);
2252                                                                         }
2253                                                         }
2254                                                         if (check_col(pinfo->cinfo, COL_INFO))
2255                                                         {
2256                                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " (%d bytes)", iSizePayload - iHeadersLength);
2257                                                         }
2258
2259                                                         {
2260                                                                 /* Call subdissector for the payload */
2261                                                                 tvbuff_t* next_tvb = NULL;
2262                                                                 struct mqinfo mqinfo;
2263                                                                 /* Format, encoding and character set are "data type" information, not subprotocol information */
2264                                                                 mqinfo.encoding = tvb_get_guint32_endian(tvb, tMsgProps.iOffsetEncoding, bLittleEndian);
2265                                                                 mqinfo.ccsid    = tvb_get_guint32_endian(tvb, tMsgProps.iOffsetCcsid, bLittleEndian);
2266                                                                 tvb_memcpy(tvb, mqinfo.format, tMsgProps.iOffsetFormat, 8);
2267                                                                 pinfo->private_data = &mqinfo;
2268                                                                 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2269                                                                 if (!dissector_try_heuristic(mq_heur_subdissector_list, next_tvb, pinfo, tree))
2270                                                                         call_dissector(data_handle, next_tvb, pinfo, tree);
2271                                                         }
2272                                                 }
2273                                                 offset = tvb_length(tvb);
2274                                         }
2275                                         /* After all recognised structures have been dissected, process remaining structure*/
2276                                         if (tvb_length_remaining(tvb, offset) >= 4)
2277                                         {
2278                                                 structId = tvb_get_ntohl(tvb, offset);
2279                                                 if (tree)
2280                                                 {
2281                                                         proto_tree_add_text(mqroot_tree, tvb, offset, -1, val_to_str(structId, mq_structid_vals, "Unknown (0x%08x)"));
2282                                                 }
2283                                         }
2284                                 }
2285                                 else
2286                                 {
2287                                         /* This is a MQ segment continuation (if MQ reassembly is not enabled) */
2288                                         if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " [Unreassembled MQ]");
2289                                         call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
2290                                 }
2291                         }
2292                 }
2293                 else
2294                 {
2295                         /* This packet is a TCP continuation of a segment (if desegmentation is not enabled) */
2296                         if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " [Undesegmented]");
2297                         if (tree)
2298                         {
2299                                 proto_tree_add_item(tree, proto_mq, tvb, offset, -1, FALSE);
2300                         }
2301                         call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
2302                 }
2303         }
2304 }
2305
2306
2307 static void
2308 reassemble_mq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2309 {
2310         /* Reassembly of the MQ messages that span several PDU (several TSH) */
2311         /* Typically a TCP PDU is 1460 bytes and a MQ PDU is 32766 bytes */
2312         if (tvb_length(tvb) >= 28)
2313         {
2314                 guint32 structId;
2315                 structId = tvb_get_ntohl(tvb, 0);
2316
2317                 if (structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC)
2318                 {
2319                         guint8 iControlFlags = 0;
2320                         guint32 iSegmentLength = 0;
2321                         guint32 iBeginLength = 0;
2322                         guint8 opcode;
2323                         gboolean bFirstSegment;
2324                         gboolean bLastSegment;
2325                         opcode = tvb_get_guint8(tvb, 9);
2326                         iControlFlags = tvb_get_guint8(tvb, 10);
2327                         iSegmentLength = tvb_get_ntohl(tvb, 4);
2328                         bFirstSegment = ((iControlFlags & MQ_TCF_FIRST) != 0);
2329                         bLastSegment = ((iControlFlags & MQ_TCF_LAST) != 0);
2330
2331                         if (opcode > 0x80 && !(bFirstSegment && bLastSegment))
2332                         {
2333                                 /* Optimisation : only fragmented segments go through the reassembly process */
2334                                 if (mq_reassembly)
2335                                 {
2336                                         tvbuff_t* next_tvb;
2337                                         fragment_data* fd_head;
2338                                         guint32 iConnectionId = (pinfo->srcport + pinfo->destport);
2339                                         if (opcode > 0x80 && !bFirstSegment) iBeginLength = 28;
2340                                         fd_head = fragment_add_seq_next(tvb, iBeginLength, pinfo, iConnectionId, mq_fragment_table, mq_reassembled_table, iSegmentLength - iBeginLength, !bLastSegment);
2341                                         if (fd_head != NULL && pinfo->fd->num == fd_head->reassembled_in)
2342                                         {
2343                                                 /* Reassembly finished */
2344                                                 if (fd_head->next != NULL)
2345                                                 {
2346                                                         /* 2 or more fragments */
2347                                                         next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
2348                                                         tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2349                                                         add_new_data_source(pinfo, next_tvb, "Reassembled MQ");
2350                                                 }
2351                                                 else
2352                                                 {
2353                                                         /* Only 1 fragment */
2354                                                         next_tvb = tvb;
2355                                                 }
2356                                                 dissect_mq_pdu(next_tvb, pinfo, tree);
2357                                                 return;
2358                                         }
2359                                         else
2360                                         {
2361                                                 /* Reassembly in progress */
2362                                                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQ");
2363                                                 if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s [Reassembled MQ]", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
2364                                                 if (tree)
2365                                                 {
2366                                                         proto_item* ti = NULL;
2367                                                         ti = proto_tree_add_item(tree, proto_mq, tvb, 0, -1, FALSE);
2368                                                         proto_item_append_text(ti, " (%s) [Reassembled MQ]", val_to_str(opcode, mq_opcode_vals, "Unknown (0x%02x)"));
2369                                                 }
2370                                                 return;
2371                                         }
2372                                 }
2373                                 else
2374                                 {
2375                                         dissect_mq_pdu(tvb, pinfo, tree);
2376                                         if (bFirstSegment)
2377                                         {
2378                                                 /* MQ segment is the first of a unreassembled series */
2379                                                 if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " [Unreassembled MQ]");
2380                                         }
2381                                         return;
2382                                 }
2383                         }
2384                         /* Reassembly not enabled or non-fragmented message */
2385                         dissect_mq_pdu(tvb, pinfo, tree);
2386                         return;
2387                 }
2388         }
2389 }
2390
2391 static guint
2392 get_mq_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2393 {
2394         if (tvb_length_remaining(tvb, offset) >= 8)
2395         {
2396                 if ((tvb_get_ntohl(tvb, 0) == MQ_STRUCTID_TSH || tvb_get_ntohl(tvb, 0) == MQ_STRUCTID_TSH_EBCDIC))
2397                         return tvb_get_ntohl(tvb, offset + 4);
2398         }
2399         return 0;
2400 }
2401
2402 static void
2403 dissect_mq_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2404 {
2405         tcp_dissect_pdus(tvb, pinfo, tree, mq_desegment, 28, get_mq_pdu_len, reassemble_mq);
2406 }
2407
2408 static void
2409 dissect_mq_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2410 {
2411         /* Since SPX has no standard desegmentation, MQ cannot be performed as well */
2412         dissect_mq_pdu(tvb, pinfo, tree);
2413 }
2414
2415 static gboolean
2416 dissect_mq_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint iProto)
2417 {
2418         if (tvb_length(tvb) >= 28)
2419         {
2420                 guint32 structId;
2421                 guint8 cEndian;
2422                 structId = tvb_get_ntohl(tvb, 0);
2423                 cEndian = tvb_get_guint8(tvb, 8);
2424
2425                 if ((structId == MQ_STRUCTID_TSH || structId == MQ_STRUCTID_TSH_EBCDIC)
2426                         && (cEndian == MQ_LITTLE_ENDIAN || cEndian == MQ_BIG_ENDIAN))
2427                 {
2428                         /* Register this dissector for this conversation */
2429                         conversation_t  *conversation = NULL;
2430                         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2431                         if (conversation == NULL)
2432                         {
2433                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2434                         }
2435                         if (iProto == MQ_XPT_TCP) conversation_set_dissector(conversation, mq_tcp_handle);
2436
2437                         /* Dissect the packet */
2438                         reassemble_mq(tvb, pinfo, tree);
2439                         return TRUE;
2440                 }
2441         }
2442         return FALSE;
2443 }
2444
2445 static gboolean
2446 dissect_mq_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2447 {
2448         return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_TCP);
2449 }
2450
2451 static gboolean
2452 dissect_mq_heur_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2453 {
2454         return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_NETBIOS);
2455 }
2456
2457 static gboolean
2458 dissect_mq_heur_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2459 {
2460         return dissect_mq_heur(tvb, pinfo, tree, MQ_XPT_HTTP);
2461 }
2462
2463 static void
2464 mq_init(void)
2465 {
2466         fragment_table_init(&mq_fragment_table);
2467         reassembled_table_init(&mq_reassembled_table);
2468 }
2469
2470 void
2471 proto_register_mq(void)
2472 {
2473   static hf_register_info hf[] = {
2474    { &hf_mq_tsh_structid,
2475       { "TSH structid", "mq.tsh.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "TSH structid", HFILL }},
2476
2477     { &hf_mq_tsh_packetlength,
2478       { "MQ Segment length", "mq.tsh.seglength", FT_UINT32, BASE_DEC, NULL, 0x0, "TSH MQ Segment length", HFILL }},
2479
2480     { &hf_mq_tsh_byteorder,
2481       { "Byte order", "mq.tsh.byteorder", FT_UINT8, BASE_HEX, VALS(mq_byteorder_vals), 0x0, "TSH Byte order", HFILL }},
2482
2483     { &hf_mq_tsh_opcode,
2484       { "Segment type", "mq.tsh.type", FT_UINT8, BASE_HEX, VALS(mq_opcode_vals), 0x0, "TSH MQ segment type", HFILL }},
2485
2486     { &hf_mq_tsh_controlflags,
2487       { "Control flags", "mq.tsh.cflags", FT_UINT8, BASE_HEX, NULL, 0x0, "TSH Control flags", HFILL }},
2488
2489     { &hf_mq_tsh_reserved,
2490       { "Reserved", "mq.tsh.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, "TSH Reserved", HFILL }},
2491
2492     { &hf_mq_tsh_luwid,
2493       { "Logical unit of work identifier", "mq.tsh.luwid", FT_BYTES, BASE_HEX, NULL, 0x0, "TSH logical unit of work identifier", HFILL }},
2494
2495     { &hf_mq_tsh_encoding,
2496       { "Encoding", "mq.tsh.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "TSH Encoding", HFILL }},
2497
2498     { &hf_mq_tsh_ccsid,
2499       { "Character set", "mq.tsh.ccsid", FT_UINT16, BASE_DEC, NULL, 0x0, "TSH CCSID", HFILL }},
2500
2501     { &hf_mq_tsh_padding,
2502       { "Padding", "mq.tsh.padding", FT_UINT16, BASE_HEX, NULL, 0x0, "TSH Padding", HFILL }},
2503
2504     { &hf_mq_tsh_tcf_confirmreq,
2505       { "Confirm request", "mq.tsh.tcf.confirmreq", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_CONFIRM_REQUEST, "TSH TCF Confirm request", HFILL }},
2506
2507     { &hf_mq_tsh_tcf_error,
2508       { "Error", "mq.tsh.tcf.error", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_ERROR, "TSH TCF Error", HFILL }},
2509
2510     { &hf_mq_tsh_tcf_reqclose,
2511       { "Request close", "mq.tsh.tcf.reqclose", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_REQUEST_CLOSE, "TSH TCF Request close", HFILL }},
2512
2513     { &hf_mq_tsh_tcf_closechann,
2514       { "Close channel", "mq.tsh.tcf.closechann", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_CLOSE_CHANNEL, "TSH TCF Close channel", HFILL }},
2515
2516     { &hf_mq_tsh_tcf_first,
2517       { "First", "mq.tsh.tcf.first", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_FIRST, "TSH TCF First", HFILL }},
2518
2519     { &hf_mq_tsh_tcf_last,
2520       { "Last", "mq.tsh.tcf.last", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_LAST, "TSH TCF Last", HFILL }},
2521
2522     { &hf_mq_tsh_tcf_reqacc,
2523       { "Request accepted", "mq.tsh.tcf.reqacc", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_REQUEST_ACCEPTED, "TSH TCF Request accepted", HFILL }},
2524
2525     { &hf_mq_tsh_tcf_dlq,
2526       { "DLQ used", "mq.tsh.tcf.dlq", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_TCF_DLQ_USED, "TSH TCF DLQ used", HFILL }},
2527
2528     { &hf_mq_api_replylength,
2529       { "Reply length", "mq.api.replylength", FT_UINT32, BASE_DEC, NULL, 0x0, "API Reply length", HFILL }},
2530
2531     { &hf_mq_api_completioncode,
2532       { "Completion code", "mq.api.completioncode", FT_UINT32, BASE_DEC, NULL, 0x0, "API Completion code", HFILL }},
2533
2534     { &hf_mq_api_reasoncode,
2535       { "Reason code", "mq.api.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "API Reason code", HFILL }},
2536
2537     { &hf_mq_api_objecthandle,
2538       { "Object handle", "mq.api.hobj", FT_UINT32, BASE_HEX, NULL, 0x0, "API Object handle", HFILL }},
2539
2540     { &hf_mq_id_icf_msgseq,
2541       { "Message sequence", "mq.id.icf.msgseq", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_MSG_SEQ, "ID ICF Message sequence", HFILL }},
2542
2543     { &hf_mq_id_icf_convcap,
2544       { "Conversion capable", "mq.id.icf.convcap", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_CONVERSION_CAPABLE, "ID ICF Conversion capable", HFILL }},
2545
2546     { &hf_mq_id_icf_splitmsg,
2547       { "Split messages", "mq.id.icf.splitmsg", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_SPLIT_MESSAGE, "ID ICF Split message", HFILL }},
2548
2549     { &hf_mq_id_icf_mqreq,
2550       { "MQ request", "mq.id.icf.mqreq", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_MQREQUEST, "ID ICF MQ request", HFILL }},
2551
2552     { &hf_mq_id_icf_svrsec,
2553       { "Server connection security", "mq.id.icf.svrsec", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_SVRCONN_SECURITY, "ID ICF Server connection security", HFILL }},
2554
2555     { &hf_mq_id_icf_runtime,
2556       { "Runtime application", "mq.id.icf.runtime", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_ICF_RUNTIME, "ID ICF Runtime application", HFILL }},
2557
2558     { &hf_mq_msh_structid,
2559       { "MSH structid", "mq.msh.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MSH structid", HFILL }},
2560
2561     { &hf_mq_msh_seqnum,
2562       { "Sequence number", "mq.msh.seqnum", FT_UINT32, BASE_DEC, NULL, 0x0, "MSH sequence number", HFILL }},
2563
2564     { &hf_mq_msh_datalength,
2565       { "Buffer length", "mq.msh.buflength", FT_UINT32, BASE_DEC, NULL, 0x0, "MSH buffer length", HFILL }},
2566
2567     { &hf_mq_msh_unknown1,
2568       { "Unknown1", "mq.msh.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "MSH unknown1", HFILL }},
2569
2570     { &hf_mq_msh_msglength,
2571       { "Message length", "mq.msh.msglength", FT_UINT32, BASE_DEC, NULL, 0x0, "MSH message length", HFILL }},
2572
2573     { &hf_mq_xqh_structid,
2574       { "XQH structid", "mq.xqh.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "XQH structid", HFILL }},
2575
2576     { &hf_mq_xqh_version,
2577       { "Version", "mq.xqh.version", FT_UINT32, BASE_DEC, NULL, 0x0, "XQH version", HFILL }},
2578
2579     { &hf_mq_xqh_remoteq,
2580       { "Remote queue", "mq.xqh.remoteq", FT_STRINGZ, BASE_DEC, NULL, 0x0, "XQH remote queue", HFILL }},
2581
2582     { &hf_mq_xqh_remoteqmgr,
2583       { "Remote queue manager", "mq.xqh.remoteqmgr", FT_STRINGZ, BASE_DEC, NULL, 0x0, "XQH remote queue manager", HFILL }},
2584
2585     { &hf_mq_id_structid,
2586       { "ID structid", "mq.id.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "ID structid", HFILL }},
2587
2588     { &hf_mq_id_level,
2589       { "FAP level", "mq.id.level", FT_UINT8, BASE_DEC, NULL, 0x0, "ID Formats And Protocols level", HFILL }},
2590
2591     { &hf_mq_id_flags,
2592       { "Flags", "mq.id.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "ID flags", HFILL }},
2593
2594     { &hf_mq_id_unknown2,
2595       { "Unknown2", "mq.id.unknown2", FT_UINT8, BASE_HEX, NULL, 0x0, "ID unknown2", HFILL }},
2596
2597     { &hf_mq_id_ieflags,
2598       { "Initial error flags", "mq.id.ief", FT_UINT8, BASE_HEX, NULL, 0x0, "ID initial error flags", HFILL }},
2599
2600     { &hf_mq_id_unknown4,
2601       { "Unknown4", "mq.id.unknown4", FT_UINT16, BASE_HEX, NULL, 0x0, "ID unknown4", HFILL }},
2602
2603     { &hf_mq_id_maxmsgperbatch,
2604       { "Maximum messages per batch", "mq.id.maxmsgperbatch", FT_UINT16, BASE_DEC, NULL, 0x0, "ID max msg per batch", HFILL }},
2605
2606     { &hf_mq_id_maxtransmissionsize,
2607       { "Maximum transmission size", "mq.id.maxtranssize", FT_UINT32, BASE_DEC, NULL, 0x0, "ID max trans size", HFILL }},
2608
2609     { &hf_mq_id_maxmsgsize,
2610       { "Maximum message size", "mq.id.maxmsgsize", FT_UINT32, BASE_DEC, NULL, 0x0, "ID max msg size", HFILL }},
2611
2612     { &hf_mq_id_sequencewrapvalue,
2613       { "Sequence wrap value", "mq.id.seqwrap", FT_UINT32, BASE_DEC, NULL, 0x0, "ID seq wrap value", HFILL }},
2614
2615     { &hf_mq_id_channel,
2616       { "Channel name", "mq.id.channelname", FT_STRINGZ, BASE_HEX, NULL, 0x0, "ID channel name", HFILL }},
2617
2618     { &hf_mq_id_capflags,
2619       { "Capability flags", "mq.id.capflags", FT_UINT8, BASE_HEX, NULL, 0x0, "ID Capability flags", HFILL }},
2620
2621     { &hf_mq_id_unknown5,
2622       { "Unknown5", "mq.id.unknown5", FT_UINT8, BASE_HEX, NULL, 0x0, "ID unknown5", HFILL }},
2623
2624     { &hf_mq_id_ccsid,
2625       { "Character set", "mq.id.ccsid", FT_UINT16, BASE_DEC, NULL, 0x0, "ID character set", HFILL }},
2626
2627     { &hf_mq_id_queuemanager,
2628       { "Queue manager", "mq.id.qm", FT_STRINGZ, BASE_HEX, NULL, 0x0, "ID Queue manager", HFILL }},
2629
2630     { &hf_mq_id_heartbeatinterval,
2631       { "Heartbeat interval", "mq.id.hbint", FT_UINT32, BASE_DEC, NULL, 0x0, "ID Heartbeat interval", HFILL }},
2632
2633     { &hf_mq_id_unknown6,
2634       { "Unknown6", "mq.id.unknown6", FT_UINT16, BASE_HEX, NULL, 0x0, "ID unknown6", HFILL }},
2635
2636     { &hf_mq_id_ief_ccsid,
2637       { "Invalid CCSID", "mq.id.ief.ccsid", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_CCSID, "ID invalid CCSID", HFILL }},
2638
2639     { &hf_mq_id_ief_enc,
2640       { "Invalid encoding", "mq.id.ief.enc", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_ENCODING, "ID invalid encoding", HFILL }},
2641
2642     { &hf_mq_id_ief_mxtrsz,
2643       { "Invalid maximum transmission size", "mq.id.ief.mxtrsz", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_MAX_TRANSMISSION_SIZE, "ID invalid maximum transmission size", HFILL }},
2644
2645     { &hf_mq_id_ief_fap,
2646       { "Invalid FAP level", "mq.id.ief.fap", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_FAP_LEVEL, "ID invalid FAP level", HFILL }},
2647
2648     { &hf_mq_id_ief_mxmsgsz,
2649       { "Invalid message size", "mq.id.ief.mxmsgsz", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_MAX_MSG_SIZE, "ID invalid message size", HFILL }},
2650
2651     { &hf_mq_id_ief_mxmsgpb,
2652       { "Invalid maximum message per batch", "mq.id.ief.mxmsgpb", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_MAX_MSG_PER_BATCH, "ID maximum message per batch", HFILL }},
2653
2654     { &hf_mq_id_ief_seqwrap,
2655       { "Invalid sequence wrap value", "mq.id.ief.seqwrap", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_SEQ_WRAP_VALUE, "ID invalid sequence wrap value", HFILL }},
2656
2657     { &hf_mq_id_ief_hbint,
2658       { "Invalid heartbeat interval", "mq.id.ief.hbint", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_IEF_HEARTBEAT_INTERVAL, "ID invalid heartbeat interval", HFILL }},
2659
2660     { &hf_mq_uid_structid,
2661       { "UID structid", "mq.uid.structid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "UID structid", HFILL }},
2662
2663     { &hf_mq_uid_userid,
2664       { "User ID", "mq.uid.userid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "UID structid", HFILL }},
2665
2666     { &hf_mq_uid_password,
2667       { "Password", "mq.uid.password", FT_STRINGZ, BASE_HEX, NULL, 0x0, "UID password", HFILL }},
2668
2669     { &hf_mq_uid_longuserid,
2670       { "Long User ID", "mq.uid.longuserid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "UID long user id", HFILL }},
2671
2672     { &hf_mq_uid_securityid,
2673       { "Security ID", "mq.uid.securityid", FT_BYTES, BASE_HEX, NULL, 0x0, "UID security id", HFILL }},
2674
2675     { &hf_mq_conn_queuemanager,
2676       { "Queue manager", "mq.conn.qm", FT_STRINGZ, BASE_HEX, NULL, 0x0, "CONN queue manager", HFILL }},
2677
2678     { &hf_mq_conn_appname,
2679       { "Application name", "mq.conn.appname", FT_STRINGZ, BASE_HEX, NULL, 0x0, "CONN application name", HFILL }},
2680
2681     { &hf_mq_conn_apptype,
2682       { "Application type", "mq.conn.apptype", FT_INT32, BASE_DEC, NULL, 0x0, "CONN application type", HFILL }},
2683
2684     { &hf_mq_conn_acttoken,
2685       { "Accounting token", "mq.conn.acttoken", FT_BYTES, BASE_HEX, NULL, 0x0, "CONN accounting token", HFILL }},
2686
2687     { &hf_mq_conn_version,
2688       { "Version", "mq.conn.version", FT_UINT32, BASE_DEC, VALS(mq_conn_version_vals), 0x0, "CONN version", HFILL }},
2689
2690     { &hf_mq_conn_options,
2691       { "Options", "mq.conn.options", FT_UINT32, BASE_HEX, NULL, 0x0, "CONN options", HFILL }},
2692
2693     { &hf_mq_inq_nbsel,
2694       { "Selector count", "mq.inq.nbsel", FT_UINT32, BASE_DEC, NULL, 0x0, "INQ Selector count", HFILL }},
2695
2696     { &hf_mq_inq_nbint,
2697       { "Integer count", "mq.inq.nbint", FT_UINT32, BASE_DEC, NULL, 0x0, "INQ Integer count", HFILL }},
2698
2699     { &hf_mq_inq_charlen,
2700       { "Character length", "mq.inq.charlen", FT_UINT32, BASE_DEC, NULL, 0x0, "INQ Character length", HFILL }},
2701
2702     { &hf_mq_inq_sel,
2703       { "Selector", "mq.inq.sel", FT_UINT32, BASE_DEC, NULL, 0x0, "INQ Selector", HFILL }},
2704
2705     { &hf_mq_inq_intvalue,
2706       { "Integer value", "mq.inq.intvalue", FT_UINT32, BASE_DEC, NULL, 0x0, "INQ Integer value", HFILL }},
2707
2708     { &hf_mq_inq_charvalues,
2709       { "Char values", "mq.inq.charvalues", FT_STRINGZ, BASE_HEX, NULL, 0x0, "INQ Character values", HFILL }},
2710
2711     { &hf_mq_spi_verb,
2712       { "SPI Verb", "mq.spi.verb", FT_UINT32, BASE_DEC, VALS(mq_spi_verbs_vals), 0x0, "SPI Verb", HFILL }},
2713
2714     { &hf_mq_spi_version,
2715       { "Version", "mq.spi.version", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Version", HFILL }},
2716
2717     { &hf_mq_spi_length,
2718       { "Max reply size", "mq.spi.replength", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Max reply size", HFILL }},
2719
2720     { &hf_mq_spi_base_structid,
2721       { "SPI Structid", "mq.spib.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "SPI Base structid", HFILL }},
2722
2723     { &hf_mq_spi_base_version,
2724       { "Version", "mq.spib.version", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Base Version", HFILL }},
2725
2726     { &hf_mq_spi_base_length,
2727       { "Length", "mq.spib.length", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Base Length", HFILL }},
2728
2729     { &hf_mq_spi_spqo_nbverb,
2730       { "Number of verbs", "mq.spqo.nbverb", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Query Output Number of verbs", HFILL }},
2731
2732     { &hf_mq_spi_spqo_verbid,
2733       { "Verb", "mq.spqo.verb", FT_UINT32, BASE_DEC, VALS(mq_spi_verbs_vals), 0x0, "SPI Query Output VerbId", HFILL }},
2734
2735     { &hf_mq_spi_spqo_maxinoutversion,
2736       { "Max InOut Version", "mq.spqo.maxiov", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Query Output Max InOut Version", HFILL }},
2737
2738     { &hf_mq_spi_spqo_maxinversion,
2739       { "Max In Version", "mq.spqo.maxiv", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Query Output Max In Version", HFILL }},
2740
2741     { &hf_mq_spi_spqo_maxoutversion,
2742       { "Max Out Version", "mq.spqo.maxov", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Query Output Max Out Version", HFILL }},
2743
2744     { &hf_mq_spi_spqo_flags,
2745       { "Flags", "mq.spqo.flags", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Query Output flags", HFILL }},
2746
2747     { &hf_mq_spi_spai_mode,
2748       { "Mode", "mq.spai.mode", FT_UINT32, BASE_DEC, VALS(mq_spi_activate_vals), 0x0, "SPI Activate Input mode", HFILL }},
2749
2750     { &hf_mq_spi_spai_unknown1,
2751       { "Unknown1", "mq.spai.unknown1", FT_STRINGZ, BASE_DEC, NULL, 0x0, "SPI Activate Input unknown1", HFILL }},
2752
2753     { &hf_mq_spi_spai_unknown2,
2754       { "Unknown2", "mq.spai.unknown2", FT_STRINGZ, BASE_DEC, NULL, 0x0, "SPI Activate Input unknown2", HFILL }},
2755
2756     { &hf_mq_spi_spai_msgid,
2757       { "Message Id", "mq.spai.msgid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "SPI Activate Input message id", HFILL }},
2758
2759     { &hf_mq_spi_spgi_batchsize,
2760       { "Batch size", "mq.spgi.batchsize", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Get Input batch size", HFILL }},
2761
2762     { &hf_mq_spi_spgi_batchint,
2763       { "Batch interval", "mq.spgi.batchint", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Get Input batch interval", HFILL }},
2764
2765     { &hf_mq_spi_spgi_maxmsgsize,
2766       { "Max message size", "mq.spgi.maxmsgsize", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Get Input max message size", HFILL }},
2767
2768     { &hf_mq_spi_spgo_options,
2769       { "Options", "mq.spgo.options", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Get Output options", HFILL }},
2770
2771     { &hf_mq_spi_spgo_size,
2772       { "Size", "mq.spgo.size", FT_UINT32, BASE_DEC, NULL, 0x0, "SPI Get Output size", HFILL }},
2773
2774     { &hf_mq_spi_options_blank,
2775       { "Blank padded", "mq.spi.options.blank", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_SPI_OPTIONS_BLANK_PADDED, "SPI Options blank padded", HFILL }},
2776
2777     { &hf_mq_spi_options_syncpoint,
2778       { "Syncpoint", "mq.spi.options.sync", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_SPI_OPTIONS_SYNCPOINT, "SPI Options syncpoint", HFILL }},
2779
2780     { &hf_mq_spi_options_deferred,
2781       { "Deferred", "mq.spi.options.deferred", FT_BOOLEAN, 8, TFS(&flags_set_truth), MQ_SPI_OPTIONS_DEFERRED, "SPI Options deferred", HFILL }},
2782
2783     { &hf_mq_put_length,
2784       { "Data length", "mq.put.length", FT_UINT32, BASE_DEC, NULL, 0x0, "PUT Data length", HFILL }},
2785
2786     { &hf_mq_open_options,
2787       { "Options", "mq.open.options", FT_UINT32, BASE_DEC, NULL, 0x0, "OPEN options", HFILL }},
2788
2789     { &hf_mq_ping_length,
2790       { "Length", "mq.ping.length", FT_UINT32, BASE_DEC, NULL, 0x0, "PING length", HFILL }},
2791
2792     { &hf_mq_ping_buffer,
2793       { "Buffer", "mq.ping.buffer", FT_BYTES, BASE_DEC, NULL, 0x0, "PING buffer", HFILL }},
2794
2795     { &hf_mq_reset_length,
2796       { "Length", "mq.ping.length", FT_UINT32, BASE_DEC, NULL, 0x0, "RESET length", HFILL }},
2797
2798     { &hf_mq_reset_seqnum,
2799       { "Sequence number", "mq.ping.seqnum", FT_UINT32, BASE_DEC, NULL, 0x0, "RESET sequence number", HFILL }},
2800
2801     { &hf_mq_status_length,
2802       { "Length", "mq.status.length", FT_UINT32, BASE_DEC, NULL, 0x0, "STATUS length", HFILL }},
2803
2804     { &hf_mq_status_code,
2805       { "Code", "mq.status.code", FT_UINT32, BASE_DEC, VALS(mq_status_vals), 0x0, "STATUS code", HFILL }},
2806
2807     { &hf_mq_status_value,
2808       { "Value", "mq.status.value", FT_UINT32, BASE_DEC, NULL, 0x0, "STATUS value", HFILL }},
2809
2810     { &hf_mq_od_structid,
2811       { "OD structid", "mq.od.structid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OD structid", HFILL }},
2812
2813     { &hf_mq_od_version,
2814       { "Version", "mq.od.version", FT_UINT32, BASE_DEC, NULL, 0x0, "OD version", HFILL }},
2815
2816     { &hf_mq_od_objecttype,
2817       { "Object type", "mq.od.objtype", FT_UINT32, BASE_DEC, NULL, 0x0, "OD object type", HFILL }},
2818
2819     { &hf_mq_od_objectname,
2820       { "Object name", "mq.od.objname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "OD object name", HFILL }},
2821
2822     { &hf_mq_od_objectqmgrname,
2823       { "Object queue manager name", "mq.od.objqmgrname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "OD object queue manager name", HFILL }},
2824
2825     { &hf_mq_od_dynamicqname,
2826       { "Dynamic queue name", "mq.od.dynqname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "OD dynamic queue name", HFILL }},
2827
2828     { &hf_mq_od_alternateuserid,
2829       { "Alternate user id", "mq.od.altuserid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "OD alternate userid", HFILL }},
2830
2831     { &hf_mq_od_recspresent,
2832       { "Number of records", "mq.od.nbrrec", FT_UINT32, BASE_DEC, NULL, 0x0, "OD number of records", HFILL }},
2833
2834     { &hf_mq_od_knowndestcount,
2835       { "Known destination count", "mq.od.kdestcount", FT_UINT32, BASE_DEC, NULL, 0x0, "OD known destination count", HFILL }},
2836
2837     { &hf_mq_od_unknowndestcount,
2838       { "Unknown destination count", "mq.od.udestcount", FT_UINT32, BASE_DEC, NULL, 0x0, "OD unknown destination count", HFILL }},
2839
2840     { &hf_mq_od_invaliddestcount,
2841       { "Invalid destination count", "mq.od.idestcount", FT_UINT32, BASE_DEC, NULL, 0x0, "OD invalid destination count", HFILL }},
2842
2843     { &hf_mq_od_objectrecoffset,
2844       { "Offset of first OR", "mq.od.offsetor", FT_UINT32, BASE_DEC, NULL, 0x0, "OD offset of first OR", HFILL }},
2845
2846     { &hf_mq_od_responserecoffset,
2847       { "Offset of first RR", "mq.od.offsetrr", FT_UINT32, BASE_DEC, NULL, 0x0, "OD offset of first RR", HFILL }},
2848
2849     { &hf_mq_od_objectrecptr,
2850       { "Address of first OR", "mq.od.addror", FT_UINT32, BASE_HEX, NULL, 0x0, "OD address of first OR", HFILL }},
2851
2852     { &hf_mq_od_responserecptr,
2853       { "Address of first RR", "mq.od.addrrr", FT_UINT32, BASE_HEX, NULL, 0x0, "OD address of first RR", HFILL }},
2854
2855     { &hf_mq_od_alternatesecurityid,
2856       { "Alternate security id", "mq.od.altsecid", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OD alternate security id", HFILL }},
2857
2858     { &hf_mq_od_resolvedqname,
2859       { "Resolved queue name", "mq.od.resolvq", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OD resolved queue name", HFILL }},
2860
2861     { &hf_mq_od_resolvedqmgrname,
2862       { "Resolved queue manager name", "mq.od.resolvqmgr", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OD resolved queue manager name", HFILL }},
2863
2864     { &hf_mq_or_objname,
2865       { "Object name", "mq.od.objname", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OR object name", HFILL }},
2866
2867     { &hf_mq_or_objqmgrname,
2868       { "Object queue manager name", "mq.od.objqmgrname", FT_STRINGZ, BASE_HEX, NULL, 0x0, "OR object queue manager name", HFILL }},
2869
2870     { &hf_mq_rr_completioncode,
2871       { "Completion code", "mq.rr.completioncode", FT_UINT32, BASE_DEC, NULL, 0x0, "OR completion code", HFILL }},
2872
2873     { &hf_mq_rr_reasoncode,
2874       { "Reason code", "mq.rr.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "OR reason code", HFILL }},
2875
2876     { &hf_mq_pmr_msgid,
2877       { "Message Id", "mq.pmr.msgid", FT_BYTES, BASE_DEC, NULL, 0x0, "PMR Message Id", HFILL }},
2878
2879     { &hf_mq_pmr_correlid,
2880       { "Correlation Id", "mq.pmr.correlid", FT_BYTES, BASE_DEC, NULL, 0x0, "PMR Correlation Id", HFILL }},
2881
2882     { &hf_mq_pmr_groupid,
2883       { "GroupId", "mq.pmr.groupid", FT_BYTES, BASE_DEC, NULL, 0x0, "PMR GroupId", HFILL }},
2884
2885     { &hf_mq_pmr_feedback,
2886       { "Feedback", "mq.pmr.feedback", FT_UINT32, BASE_DEC, NULL, 0x0, "PMR Feedback", HFILL }},
2887
2888     { &hf_mq_pmr_acttoken,
2889       { "Accounting token", "mq.pmr.acttoken", FT_BYTES, BASE_DEC, NULL, 0x0, "PMR accounting token", HFILL }},
2890
2891     { &hf_mq_md_structid,
2892       { "MD structid", "mq.md.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD structid", HFILL }},
2893
2894     { &hf_mq_md_version,
2895       { "Version", "mq.md.version", FT_UINT32, BASE_DEC, NULL, 0x0, "MD version", HFILL }},
2896
2897     { &hf_mq_md_report,
2898       { "Report", "mq.md.report", FT_UINT32, BASE_DEC, NULL, 0x0, "MD report", HFILL }},
2899
2900     { &hf_mq_md_msgtype,
2901       { "Message type", "mq.md.msgtype", FT_UINT32, BASE_DEC, NULL, 0x0, "MD message type", HFILL }},
2902
2903     { &hf_mq_md_expiry,
2904       { "Expiry", "mq.md.expiry", FT_INT32, BASE_DEC, NULL, 0x0, "MD expiry", HFILL }},
2905
2906     { &hf_mq_md_feedback,
2907       { "Feedback", "mq.md.feedback", FT_UINT32, BASE_DEC, NULL, 0x0, "MD feedback", HFILL }},
2908
2909     { &hf_mq_md_encoding,
2910       { "Encoding", "mq.md.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "MD encoding", HFILL }},
2911
2912     { &hf_mq_md_ccsid,
2913       { "Character set", "mq.md.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "MD character set", HFILL }},
2914
2915     { &hf_mq_md_format,
2916       { "Format", "mq.md.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD format", HFILL }},
2917
2918     { &hf_mq_md_priority,
2919       { "Priority", "mq.md.priority", FT_INT32, BASE_DEC, NULL, 0x0, "MD priority", HFILL }},
2920
2921     { &hf_mq_md_persistence,
2922       { "Persistence", "mq.md.persistence", FT_UINT32, BASE_DEC, NULL, 0x0, "MD persistence", HFILL }},
2923
2924     { &hf_mq_md_msgid,
2925       { "MessageId", "mq.md.msgid", FT_BYTES, BASE_DEC, NULL, 0x0, "MD Message Id", HFILL }},
2926
2927     { &hf_mq_md_correlid,
2928       { "CorrelationId", "mq.md.correlid", FT_BYTES, BASE_DEC, NULL, 0x0, "MD Correlation Id", HFILL }},
2929
2930     { &hf_mq_md_backountcount,
2931       { "Backount count", "mq.md.backount", FT_UINT32, BASE_DEC, NULL, 0x0, "MD Backount count", HFILL }},
2932
2933     { &hf_mq_md_replytoq,
2934       { "ReplyToQ", "mq.md.correlid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD ReplyTo queue manager", HFILL }},
2935
2936     { &hf_mq_md_replytoqmgr,
2937       { "ReplyToQMgr", "mq.md.correlid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD ReplyTo queue", HFILL }},
2938
2939     { &hf_mq_md_userid,
2940       { "UserId", "mq.md.userid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD UserId", HFILL }},
2941
2942     { &hf_mq_md_acttoken,
2943       { "Accounting token", "mq.md.acttoken", FT_BYTES, BASE_DEC, NULL, 0x0, "MD accounting token", HFILL }},
2944
2945     { &hf_mq_md_appliddata,
2946       { "ApplicationId data", "mq.md.appldata", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put applicationId data", HFILL }},
2947
2948     { &hf_mq_md_putappltype,
2949       { "Put Application Type", "mq.md.appltype", FT_INT32, BASE_DEC, NULL, 0x0, "MD Put application type", HFILL }},
2950
2951     { &hf_mq_md_putapplname,
2952       { "Put Application Name", "mq.md.applname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put application name", HFILL }},
2953
2954     { &hf_mq_md_putdate,
2955       { "Put date", "mq.md.date", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put date", HFILL }},
2956
2957     { &hf_mq_md_puttime,
2958       { "Put time", "mq.md.time", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Put time", HFILL }},
2959
2960     { &hf_mq_md_applorigindata,
2961       { "Application original data", "mq.md.origdata", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Application original data", HFILL }},
2962
2963     { &hf_mq_md_groupid,
2964       { "GroupId", "mq.md.groupid", FT_BYTES, BASE_DEC, NULL, 0x0, "MD GroupId", HFILL }},
2965
2966     { &hf_mq_md_msgseqnumber,
2967       { "Message sequence number", "mq.md.msgseqnumber", FT_UINT32, BASE_DEC, NULL, 0x0, "MD Message sequence number", HFILL }},
2968
2969     { &hf_mq_md_offset,
2970       { "Offset", "mq.md.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "MD Offset", HFILL }},
2971
2972     { &hf_mq_md_msgflags,
2973       { "Message flags", "mq.md.msgflags", FT_UINT32, BASE_HEX, NULL, 0x0, "MD Message flags", HFILL }},
2974
2975     { &hf_mq_md_originallength,
2976       { "Original length", "mq.md.origdata", FT_INT32, BASE_DEC, NULL, 0x0, "MD Original length", HFILL }},
2977
2978     { &hf_mq_md_hidden_lastformat,
2979       { "Last format", "mq.md.lastformat", FT_STRINGZ, BASE_DEC, NULL, 0x0, "MD Last format", HFILL }},
2980
2981     { &hf_mq_dlh_structid,
2982       { "DLH structid", "mq.dlh.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH structid", HFILL }},
2983
2984     { &hf_mq_dlh_version,
2985       { "Version", "mq.dlh.version", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH version", HFILL }},
2986
2987     { &hf_mq_dlh_reason,
2988       { "Reason", "mq.dlh.reason", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH reason", HFILL }},
2989
2990     { &hf_mq_dlh_destq,
2991       { "Destination queue", "mq.dlh.destq", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH destination queue", HFILL }},
2992
2993     { &hf_mq_dlh_destqmgr,
2994       { "Destination queue manager", "mq.dlh.destqmgr", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH destination queue manager", HFILL }},
2995
2996     { &hf_mq_dlh_encoding,
2997       { "Encoding", "mq.dlh.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "DLH encoding", HFILL }},
2998
2999     { &hf_mq_dlh_ccsid,
3000       { "Character set", "mq.dlh.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "DLH character set", HFILL }},
3001
3002     { &hf_mq_dlh_format,
3003       { "Format", "mq.dlh.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH format", HFILL }},
3004
3005     { &hf_mq_dlh_putappltype,
3006       { "Put application type", "mq.dlh.putappltype", FT_INT32, BASE_DEC, NULL, 0x0, "DLH put application type", HFILL }},
3007
3008     { &hf_mq_dlh_putapplname,
3009       { "Put application name", "mq.dlh.putapplname", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH put application name", HFILL }},
3010
3011     { &hf_mq_dlh_putdate,
3012       { "Put date", "mq.dlh.putdate", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH put date", HFILL }},
3013
3014     { &hf_mq_dlh_puttime,
3015       { "Put time", "mq.dlh.puttime", FT_STRINGZ, BASE_DEC, NULL, 0x0, "DLH put time", HFILL }},
3016
3017     { &hf_mq_dh_putmsgrecfields,
3018       { "Flags PMR", "mq.dh.flagspmr", FT_UINT32, BASE_DEC, NULL, 0x0, "DH flags PMR", HFILL }},
3019
3020     { &hf_mq_dh_recspresent,
3021       { "Number of records", "mq.dh.nbrrec", FT_UINT32, BASE_DEC, NULL, 0x0, "DH number of records", HFILL }},
3022
3023     { &hf_mq_dh_objectrecoffset,
3024       { "Offset of first OR", "mq.dh.offsetor", FT_UINT32, BASE_DEC, NULL, 0x0, "DH offset of first OR", HFILL }},
3025
3026     { &hf_mq_dh_putmsgrecoffset,
3027       { "Offset of first PMR", "mq.dh.offsetpmr", FT_UINT32, BASE_DEC, NULL, 0x0, "DH offset of first PMR", HFILL }},
3028
3029     { &hf_mq_gmo_structid,
3030       { "GMO structid", "mq.gmo.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "GMO structid", HFILL }},
3031
3032     { &hf_mq_gmo_version,
3033       { "Version", "mq.gmo.version", FT_UINT32, BASE_DEC, NULL, 0x0, "GMO version", HFILL }},
3034
3035     { &hf_mq_gmo_options,
3036       { "Options", "mq.gmo.options", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO options", HFILL }},
3037
3038     { &hf_mq_gmo_waitinterval,
3039       { "Wait Interval", "mq.gmo.waitint", FT_INT32, BASE_DEC, NULL, 0x0, "GMO wait interval", HFILL }},
3040
3041     { &hf_mq_gmo_signal1,
3042       { "Signal 1", "mq.gmo.signal1", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO signal 1", HFILL }},
3043
3044     { &hf_mq_gmo_signal2,
3045       { "Signal 2", "mq.gmo.signal2", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO signal 2", HFILL }},
3046
3047     { &hf_mq_gmo_resolvedqname,
3048       { "Resolved queue name", "mq.gmo.resolvq", FT_STRINGZ, BASE_HEX, NULL, 0x0, "GMO resolved queue name", HFILL }},
3049
3050     { &hf_mq_gmo_matchoptions,
3051       { "Match options", "mq.gmo.matchopt", FT_UINT32, BASE_HEX, NULL, 0x0, "GMO match options", HFILL }},
3052
3053     { &hf_mq_gmo_groupstatus,
3054       { "Group status", "mq.gmo.grpstat", FT_UINT8, BASE_HEX, NULL, 0x0, "GMO group status", HFILL }},
3055
3056     { &hf_mq_gmo_segmentstatus,
3057       { "Segment status", "mq.gmo.sgmtstat", FT_UINT8, BASE_HEX, NULL, 0x0, "GMO segment status", HFILL }},
3058
3059     { &hf_mq_gmo_segmentation,
3060       { "Segmentation", "mq.gmo.segmentation", FT_UINT8, BASE_HEX, NULL, 0x0, "GMO segmentation", HFILL }},
3061
3062     { &hf_mq_gmo_reserved,
3063       { "Reserved", "mq.gmo.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, "GMO reserved", HFILL }},
3064
3065     { &hf_mq_gmo_msgtoken,
3066       { "Message token", "mq.gmo.msgtoken", FT_BYTES, BASE_HEX, NULL, 0x0, "GMO message token", HFILL }},
3067
3068     { &hf_mq_gmo_returnedlength,
3069       { "Returned length", "mq.gmo.retlen", FT_INT32, BASE_DEC, NULL, 0x0, "GMO returned length", HFILL }},
3070
3071     { &hf_mq_pmo_structid,
3072       { "PMO structid", "mq.pmo.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "PMO structid", HFILL }},
3073
3074     { &hf_mq_pmo_version,
3075       { "Version", "mq.pmo.structid", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO version", HFILL }},
3076
3077     { &hf_mq_pmo_options,
3078       { "Options", "mq.pmo.options", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO options", HFILL }},
3079
3080     { &hf_mq_pmo_timeout,
3081       { "Timeout", "mq.pmo.timeout", FT_INT32, BASE_DEC, NULL, 0x0, "PMO time out", HFILL }},
3082
3083     { &hf_mq_pmo_context,
3084       { "Context", "mq.pmo.context", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO context", HFILL }},
3085
3086     { &hf_mq_pmo_knowndestcount,
3087       { "Known destination count", "mq.pmo.kdstcount", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO known destination count", HFILL }},
3088
3089     { &hf_mq_pmo_unknowndestcount,
3090       { "Unknown destination count", "mq.pmo.udestcount", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO unknown destination count", HFILL }},
3091
3092     { &hf_mq_pmo_invaliddestcount,
3093       { "Invalid destination count", "mq.pmo.idestcount", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO invalid destination count", HFILL }},
3094
3095     { &hf_mq_pmo_resolvedqname,
3096       { "Resolved queue name", "mq.pmo.resolvq", FT_STRINGZ, BASE_DEC, NULL, 0x0, "PMO resolved queue name", HFILL }},
3097
3098     { &hf_mq_pmo_resolvedqmgrname,
3099       { "Resolved queue name manager", "mq.pmo.resolvqmgr", FT_STRINGZ, BASE_DEC, NULL, 0x0, "PMO resolved queue manager name", HFILL }},
3100
3101     { &hf_mq_pmo_recspresent,
3102       { "Number of records", "mq.pmo.nbrrec", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO number of records", HFILL }},
3103
3104     { &hf_mq_pmo_putmsgrecfields,
3105       { "Flags PMR fields", "mq.pmo.flagspmr", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO flags PMR fields", HFILL }},
3106
3107     { &hf_mq_pmo_putmsgrecoffset,
3108       { "Offset of first PMR", "mq.pmo.offsetpmr", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO offset of first PMR", HFILL }},
3109
3110     { &hf_mq_pmo_responserecoffset,
3111       { "Offset of first RR", "mq.pmo.offsetrr", FT_UINT32, BASE_DEC, NULL, 0x0, "PMO offset of first RR", HFILL }},
3112
3113     { &hf_mq_pmo_putmsgrecptr,
3114       { "Address of first record", "mq.pmo.addrrec", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO address of first record", HFILL }},
3115
3116     { &hf_mq_pmo_responserecptr,
3117       { "Address of first response record", "mq.pmo.addrres", FT_UINT32, BASE_HEX, NULL, 0x0, "PMO address of first response record", HFILL }},
3118
3119     { &hf_mq_head_structid,
3120       { "Structid", "mq.head.structid", FT_STRINGZ, BASE_DEC, NULL, 0x0, "Header structid", HFILL }},
3121
3122     { &hf_mq_head_version,
3123       { "Structid", "mq.head.version", FT_UINT32, BASE_DEC, NULL, 0x0, "Header version", HFILL }},
3124
3125     { &hf_mq_head_length,
3126       { "Length", "mq.head.length", FT_UINT32, BASE_DEC, NULL, 0x0, "Header length", HFILL }},
3127
3128     { &hf_mq_head_encoding,
3129       { "Encoding", "mq.head.encoding", FT_UINT32, BASE_DEC, NULL, 0x0, "Header encoding", HFILL }},
3130
3131     { &hf_mq_head_ccsid,
3132       { "Character set", "mq.head.ccsid", FT_INT32, BASE_DEC, NULL, 0x0, "Header character set", HFILL }},
3133
3134     { &hf_mq_head_format,
3135       { "Format", "mq.head.format", FT_STRINGZ, BASE_DEC, NULL, 0x0, "Header format", HFILL }},
3136
3137     { &hf_mq_head_flags,
3138       { "Flags", "mq.head.flags", FT_UINT32, BASE_DEC, NULL, 0x0, "Header flags", HFILL }},
3139
3140     { &hf_mq_head_struct,
3141       { "Struct", "mq.head.struct", FT_BYTES, BASE_HEX, NULL, 0x0, "Header struct", HFILL }},
3142
3143     { &hf_mq_xa_length,
3144       { "Length", "mq.xa.length", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Length", HFILL }},
3145
3146     { &hf_mq_xa_returnvalue,
3147       { "Return value", "mq.xa.returnvalue", FT_INT32, BASE_DEC, VALS(mq_xaer_vals), 0x0, "XA Return Value", HFILL }},
3148
3149     { &hf_mq_xa_tmflags,
3150       { "Transaction Manager Flags", "mq.xa.tmflags", FT_UINT32, BASE_HEX, NULL, 0x0, "XA Transaction Manager Flags", HFILL }},
3151
3152     { &hf_mq_xa_rmid,
3153       { "Resource manager ID", "mq.xa.rmid", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Resource Manager ID", HFILL }},
3154
3155     { &hf_mq_xa_count,
3156       { "Number of Xid", "mq.xa.nbxid", FT_UINT32, BASE_DEC, NULL, 0x0, "XA Number of Xid", HFILL }},
3157
3158     { &hf_mq_xa_tmflags_join,
3159       { "JOIN", "mq.xa.tmflags.join", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMJOIN, "XA TM Flags JOIN", HFILL }},
3160
3161     { &hf_mq_xa_tmflags_endrscan,
3162       { "ENDRSCAN", "mq.xa.tmflags.endrscan", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMENDRSCAN, "XA TM Flags ENDRSCAN", HFILL }},
3163
3164     { &hf_mq_xa_tmflags_startrscan,
3165       { "STARTRSCAN", "mq.xa.tmflags.startrscan", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSTARTRSCAN, "XA TM Flags STARTRSCAN", HFILL }},
3166
3167     { &hf_mq_xa_tmflags_suspend,
3168       { "SUSPEND", "mq.xa.tmflags.suspend", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSUSPEND, "XA TM Flags SUSPEND", HFILL }},
3169
3170     { &hf_mq_xa_tmflags_success,
3171       { "SUCCESS", "mq.xa.tmflags.success", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMSUCCESS, "XA TM Flags SUCCESS", HFILL }},
3172
3173     { &hf_mq_xa_tmflags_resume,
3174       { "RESUME", "mq.xa.tmflags.resume", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMRESUME, "XA TM Flags RESUME", HFILL }},
3175
3176     { &hf_mq_xa_tmflags_fail,
3177       { "FAIL", "mq.xa.tmflags.fail", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMFAIL, "XA TM Flags FAIL", HFILL }},
3178
3179     { &hf_mq_xa_tmflags_onephase,
3180       { "ONEPHASE", "mq.xa.tmflags.onephase", FT_BOOLEAN, 32, TFS(&flags_set_truth), MQ_XA_TMONEPHASE, "XA TM Flags ONEPHASE", HFILL }},
3181
3182     { &hf_mq_xa_xid_formatid,
3183       { "Format ID", "mq.xa.xid.formatid", FT_INT32, BASE_DEC, NULL, 0x0, "XA Xid Format ID", HFILL }},
3184
3185     { &hf_mq_xa_xid_globalxid_length,
3186       { "Global TransactionId Length", "mq.xa.xid.gxidl", FT_UINT8, BASE_DEC, NULL, 0x0, "XA Xid Global TransactionId Length", HFILL }},
3187
3188     { &hf_mq_xa_xid_brq_length,
3189       { "Branch Qualifier Length", "mq.xa.xid.bql", FT_UINT8, BASE_DEC, NULL, 0x0, "XA Xid Branch Qualifier Length", HFILL }},
3190
3191     { &hf_mq_xa_xid_globalxid,
3192       { "Global TransactionId", "mq.xa.xid.gxid", FT_BYTES, BASE_DEC, NULL, 0x0, "XA Xid Global TransactionId", HFILL }},
3193
3194     { &hf_mq_xa_xid_brq,
3195       { "Branch Qualifier", "mq.xa.xid.bq", FT_BYTES, BASE_DEC, NULL, 0x0, "XA Xid Branch Qualifier", HFILL }},
3196
3197     { &hf_mq_xa_xainfo_length,
3198       { "Length", "mq.xa.xainfo.length", FT_UINT8, BASE_DEC, NULL, 0x0, "XA XA_info Length", HFILL }},
3199
3200     { &hf_mq_xa_xainfo_value,
3201       { "Value", "mq.xa.xainfo.value", FT_STRINGZ, BASE_DEC, NULL, 0x0, "XA XA_info Value", HFILL }}
3202
3203   };
3204   static gint *ett[] = {
3205     &ett_mq,
3206     &ett_mq_tsh,
3207     &ett_mq_tsh_tcf,
3208     &ett_mq_api,
3209     &ett_mq_msh,
3210     &ett_mq_xqh,
3211     &ett_mq_id,
3212     &ett_mq_id_icf,
3213     &ett_mq_id_ief,
3214     &ett_mq_uid,
3215     &ett_mq_conn,
3216     &ett_mq_inq,
3217     &ett_mq_spi,
3218     &ett_mq_spi_base,
3219     &ett_mq_spi_options,
3220     &ett_mq_put,
3221     &ett_mq_open,
3222     &ett_mq_ping,
3223     &ett_mq_reset,
3224     &ett_mq_status,
3225     &ett_mq_od,
3226     &ett_mq_or,
3227     &ett_mq_rr,
3228     &ett_mq_pmr,
3229     &ett_mq_md,
3230     &ett_mq_mde,
3231     &ett_mq_dlh,
3232     &ett_mq_dh,
3233     &ett_mq_gmo,
3234     &ett_mq_pmo,
3235     &ett_mq_head,
3236     &ett_mq_xa,
3237     &ett_mq_xa_tmflags,
3238     &ett_mq_xa_xid,
3239     &ett_mq_xa_info,
3240   };
3241
3242   module_t *mq_module;
3243
3244   proto_mq = proto_register_protocol("WebSphere MQ", "MQ", "mq");
3245   proto_register_field_array(proto_mq, hf, array_length(hf));
3246   proto_register_subtree_array(ett, array_length(ett));
3247
3248   register_heur_dissector_list("mq", &mq_heur_subdissector_list);
3249   register_init_routine(mq_init);
3250
3251   mq_module = prefs_register_protocol(proto_mq, NULL);
3252   prefs_register_bool_preference(mq_module, "desegment",
3253     "Reassemble MQ messages spanning multiple TCP segments",
3254     "Whether the MQ dissector should reassemble messages spanning multiple TCP segments."
3255     " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3256     &mq_desegment);
3257   prefs_register_bool_preference(mq_module, "reassembly",
3258     "Reassemble segmented MQ messages",
3259     "Whether the MQ dissector should reassemble MQ messages spanning multiple TSH segments",
3260     &mq_reassembly);
3261 }
3262
3263 void
3264 proto_reg_handoff_mq(void)
3265 {
3266         /*  Unlike some protocol (HTTP, POP3, ...) that clearly map to a standard
3267         *  class of applications (web browser, e-mail client, ...) and have a very well
3268         *  known port number, the MQ applications are most often specific to a business application */
3269
3270         mq_tcp_handle = create_dissector_handle(dissect_mq_tcp, proto_mq);
3271         mq_spx_handle = create_dissector_handle(dissect_mq_spx, proto_mq);
3272
3273         dissector_add_handle("tcp.port", mq_tcp_handle);
3274         heur_dissector_add("tcp", dissect_mq_heur_tcp, proto_mq);
3275         heur_dissector_add("netbios", dissect_mq_heur_netbios, proto_mq);
3276         heur_dissector_add("http", dissect_mq_heur_http, proto_mq);
3277         dissector_add("spx.socket", MQ_SOCKET_SPX, mq_spx_handle);
3278         data_handle = find_dissector("data");
3279
3280 }